Version 7 of Regsub -all, Match Line, and Replace, Working on a Text File V2

Updated 2024-03-27 13:27:05 by gold


Title: Regsub -all, Match Line, and Replace, Working on a Text File V2


gold Note to clean up crew. Checking end of line issues here from laptop PC editor.


Find a text in a line and replace the next line


gold 3/26/2024. Found example code on Ask, and it shall be given # 11. Seemed a useful lesson and example code on regsub and replace, if category links and Wiki page references were added to find same in the Wiki stacks.


Question: Working on a Text File V2


tclamateur : I want to find a text in a line and replace the contents of the next line with a new string. I tried regsub, but it is only matching the first line. I don't know how to go to the next line. eg:


line 5> this is line 5.

line 6> apple


with

line 5> this is line 5.

line 6> banana

Thanks


First Example


AMG: [regsub] has the -all option to replace every occurrence, not just the first.


proc replace {match replacement text} {
    # Backslash-quote special characters in match and replacement so they will
    # be interpreted as literal strings.
    regsub -all {[][*+?{}()<>|.^$]} $match {\\&} match
    regsub -all {[\\&]} $replacement {\\&} replacement

    # Perform the replacement.
    regsub -all ($match\\n)\[^\\n\]* $text \\1$replacement
}

replace "this is line 5." banana {
this is line 5.
apple
this is line 5.
another apple
this is not line 5.
yet more apples
}

This gives the following result:


none
this is line 5.
banana
this is line 5.
banana
this is not line 5.
yet more apples

Second Answer


MG offers:


proc replace2 {args} {

if { [llength $args] < 3} {
     return -code error "wrong # arguments: replace2 ?-all? ?-regexp|-glob|-exact? \$find \$replace \$text"
   }
set find [lindex $args end-2]
set replace [lindex $args end-1]
set text [lindex $args end]
set args [lrange $args 0 end-3
]
set matchtype -exact
set all ""
foreach x $args {
if {$x eq "" } {
    continue;
   } elseif { $x eq "-all" } {
     set all [list "-all"]
   } elseif { $x in [list -regexp -glob -exact] } {
     set matchtype $x
   } else {
     return -code error "unknown option '$x'"
   }
}
set text [split $text \n]
set matches [lsearch {*}$all $matchtype $text $find]
if { [llength $matches] && [lindex $matches 0] != -1 } {
     foreach x $matches {
        incr x
        set text [lreplace $text $x $x $replace]
     }
   }
return [join $text "\n"]

}

# Example:
replace2 -all -exact "this is line 5." banana {
this is line 5.
apple
this is line 5.
another apple
this is not line 5.
yet more apples
}

Two Questions for One, File 13


tclamateur: Thanks for the input. In my case I'll have only two inputs. The input "match" and the input "replacement". What to give as input for "text"?


AMG: Whatever text you want the substitution to be performed on. For instance, if you're working on a file, you'd supply the contents of that file. Then write the return value back out to the file, and you're done.


References on Wiki


regsub, a built-in Tcl command, performs substitutions based on regular expression pattern matching.

See Also

regular expressions
information about Tcl regular expressions that is not unique to any particular command
string map
subst

Synopsis

regsub ?switches? exp string subSpec ?varName?


Hidden Comments Section

Please include your wiki MONIKER and date in your comment with the same courtesy that I will give you. Thanks, gold 3/26/2024