string insert

Difference between version 5 and 6 - Previous - Next
**Overview**

[AMG]: TIP 475 [http://tip.tcl.tk/475] proposes a new [[string insert]] command to allow inserting substrings into a string at a specified index.

**Specification**

'''string insert''' ''string index insertString''

Returns a copy of ''string'' with ''insertString'' inserted at the ''index'''th character. ''index'' may be specified as described in the '''STRING INDICES''' [https://www.tcl.tk/man/tcl/TclCmd/string.htm#M54] section.

If ''index'' is start-relative, the first character inserted in the returned string will be at the specified index. If ''index'' is end-relative, the last character inserted in the returned string will be at the specified index.

If ''index'' is at or before the start of string (e.g., ''index'' is '''0'''), ''insertString'' is prepended to ''string''. If ''index'' is at or after the end of ''string'' (e.g., ''index'' is '''end'''), ''insertString'' is appended to ''string''.

**Implementation**

C implementation available here: [http://core.tcl.tk/tcl/timeline?t=amg-string-insert]

Also, here it is in [pure-Tcl]:

======
# Pure Tcl implementation of [string insert] command.
proc ::tcl::string::insert {string index insertString} {
    # Convert end-relative and TIP 176 indexes to simple integers.
    if {[regexp -expanded {
        ^(end(?![\t\n\v\f\r ])      # "end" is never followed by whitespace
        |[\t\n\v\f\r ]*[+-]?\d+)    # m, with optional leading whitespace
        (?:([+-])                   # op, omitted when index is "end"
        ([+-]?\d+))?                # n, omitted when index is "end"
        [\t\n\v\f\r ]*$             # optional whitespace (unless "end")
    } $index _ m op n]} {
        # Convert first index to an integer.
        switch $m {
            end     {set index [string length $string]}
            default {scan $m %d index}
        }

        # Add or subtract second index, if provided.
        switch $op {
            + {set index [expr {$index + $n}]}
            - {set index [expr {$index - $n}]}
        }
    } elseif {![string is integer -strict $index]} {
        # Reject invalid indexes.
        return -code error "bad index \"$index\": must be\
                integer?\[+-\]integer? or end?\[+-\]integer?"
    }

    # Concatenate the pre-insert, insertion, and post-insert strings.
    string cat [string range $string 0 [expr {$index - 1}]] $insertString\
               [string range $string $index end]
}

# Bind [string insert] to [::tcl::string::insert].
namespace ensemble configure string -map [dict replace\
        [namespace ensemble configure string -map]\
        insert ::tcl::string::insert]
======
----
'''[ML] '''

Also the following works (before 8.7) :

======
proc ::tcl::string::insert {string index insertString} {
        set endOffset [string match end* $index]
        if {$endOffset} {
                set endOffset [string range $index 3 end]
                return [string cat [string range $string 0 end+[expr $endOffset-1]] $insertString [string range $string $index end]]
        } else {
                return [string cat [string range $string 0 $index-1] $insertString [string range $string $index end]]
        }
}

======

<<categories>> Command | String Processing