I have a text which has slightly been modified by a tcl code. Now it looks as follows:
word1 word2 word3 word4 , word5 word6 word7 word8 . word9 , word10 word11 word12 ; word13 word14 word15...
As you can see, characters like . or , are removed from the words. I would like to put them into their original position, that is
word1 word2 word3 word4, word5 word6 word7 word8. word9, word10 ...
As I work with tcl 8.0, I would like to use the regsub-command if possible. (string replace is not implemented in tcl 8.0)
Any help is welcome.
Thanks in advance!
Try
regsub -all {[[:space:]]+([[:punct:]])} $text {\1} new_text
Thanks for your comments folks
regsub -all -nocase {[ \t]+([^a-z0-9])} $text {\1} new_text
Related
how to find the count of uppercase amd lower case in tcl
with this code im getting only ascii values
foreach character {H e l l o T C L} {
scan $character %c numeric
puts "ASCII character '$numeric' displays as '$character'."
}
Instead of looping through a string yourself, you can use regexp to give you a count:
set str "Hello Tcl"
puts "Uppercase: [regexp -all {[[:upper:]]} $str]"
puts "Lowercase: [regexp -all {[[:lower:]]} $str]"
I'm using [[:upper:]] and [[:lower:]] instead of [A-Z] and [a-z] because the former will correctly capture unicode upper- and lowercase, rather than just the ones in the ASCII set.
You can test each character with string is upper $character and string is lower $character. Note that non-alphabetic characters are neither upper or lower case. For more info check the documentation at https://www.tcl-lang.org/man/tcl8.6/TclCmd/string.htm#M10
I want to convert both strings into SML_CHAINS_6_* using regsub in tcl. How do I do that?
SML_CHAINS_6_1167
SML_CHAINS_6_1145
Something like:
set var1 SML_CHAINS_6_1167
regsub {\d+$} $var1 "*" var1
and same for the other. Just replacing all trailing digits with a single asterisk.
I want to regsub without exception, so as not to double I do a regsub.
example before:
regsub -all "feat" $songtitle "" songtitle
regsub -all "Feat" $songtitle "" songtitle
I want a simple one line for regsub:
regsub -all "feat" $songtitle "" songtitle
It's a little inconvenient if there are many words that I want to regsub, I want it to be simple with no exceptions in the regsub, so that only one line of each word is regsub, not two lines for uppercase and lowercase letters. thanks
You can specify the -nocase option to regsub to get it to ignore case when matching.
regsub -all -nocase {feat} $songtitle "" songtitle
You can also enable that mode of operation by putting the (?i) marker at the start of the RE:
regsub -all {(?i)feat} $songtitle "" songtitle
You probably should put some \y (a word boundary constraint) in that RE too, so that it doesn't change defeated into deed:
regsub -all {(?i)\yfeat\y} $songtitle "" songtitle
(Once you add either backslashes or square brackets to an RE, it's pretty much essential in Tcl that you put the RE in curly braces. Otherwise you end up using a disgustingly large number of backslashes…)
Also be aware of the string map command:
string map {feat "" Feat ""} $songtitle
Useful when you don't actually need regular expressions.
catch [list exec find /home/gusman/mp3 -name "*$title*" -type f -printf "%f,"] song
I cut and divide in this way:
regsub -all "," $song "\n" song
And post them this way
putserv "notice $nick :$song"
The result only posts one line
<Botnick>: Title song.mp3
Whereas in the search file there are several song titles
I want to post it like this:
<Botnick>:1 Title song.mp3
<Botnick>:2 Title song.mp3
<Botnick>:3 Title song.mp3
according to the number of search results.
Why do you print with the extra , characters and replace them afterwards with newlines, instead of using newlines directly?
I guess you're also missing a split and a foreach loop.
This works for me:
catch [list exec find /home/gusman/mp3 -name "*$title*" -type f] songs
foreach song [split $songs \n] {
putserv "notice $nick :$song"
}
Seems like a basic task, but I want to take a string that ends in something and replace the last 3 letters with something else. Here's my attempt:
set v "this is bob"
set index2 [string length $v]
set index1 [expr $index2 - 3]
set result [string replace $v index1 index2 dog]
puts $result; # I want it to now say "this is dog"
EDIT: Forgot to mention, the error message it gives me is:
bad index "index1": must be integer?[+-]integer? or end?[+-]integer?
while executing
"string replace $v index1 index2 .hdr"
invoked from within
"set result [string replace $v index1 index2 .hdr]"
(file "string_manipulation.tcl" line 7)
Here is one way to do it. Tcl recognizes tokens such as end, end-1, end-2, ... What you want is to replace from end-2 to end:
set v "this is bob"
set result [string replace $v end-2 end "dog"]
# Result now is "this is dog"
Update
If all you want to do is replacing the file extension, then use file rootname to remove the extension, then add your own:
set v filename.arm
set result [file rootname $v].hdr; # Replaces .arm with .hdr
This solution has the advantage of working with extensions of various lengths, not just 3.
Easy, you forgot you were in TCL right near the end. Instead of passing in the values of index1 and index2, you passed in the literal strings "index1" and "index2". So just add the missing dollar signs:
set result [string replace $v $index1 $index2 dog]
Voila! :-)