How to remove quotes in TCL string by using 'string map' - csv

I am really stuck with this problem for some hours now. I am writing the output of my TCL script to a .csv file. Theoretically it should have 130 lines, but it stops afther line 117, where the first times double-quotes appear. So I want to remove the double-quotes using 'string map' but all the ways I tried it outputs still doublequotes. Other caharcters are cleanly maped as I intended.
set lines [string map [list "\;" {} "," {} {"} {} "\'" {} ] $lines]
set lines [string map [list "\;" {} "," {} "\"" {} {'} {} ] $lines]
set lines [string map [list "\;" {} "," {} \" {} \' {} ] $lines]
Has anyone an idea how to correctly remove double-quotes out of a string?
Thanks!
Paul

The string map calls you use will work — all are using correctly-constructed even-length maps — but it is possible that the characters you see in the input string are not standard double quotes (") but rather their more sophisticated cousins (“, ”). There are a few other characters that can look similar too, such as a naked diaeresis (¨).

Related

Tcl: Parsing input with strings in quotes

I have the following code to split stdin into a list of strings:
set cmd [string toupper [gets stdin]]
set items [split $cmd " "]
This splits the user input into a list (items) using the space as a delimiter. It works fine for simple input such as:
HELLO 1 2 3
What I get in items:
HELLO
1
2
But how can I get the quoted string in the example below to be become one item in the list (items):
"HELLO THERE" 1 2 3
What I want in items:
HELLO THERE
1
2
How can I do this?
This is where you get into building a more complex parser. The first step towards that is switching to using regular expressions.
regexp -all -inline {"[^\"]*"|[^\"\s]+} $inputData
That will do the right thing... provided the input is well-formed and only uses double quotes for quoting. It also doesn't strip the quotes off the outside of the "words"; you'll want to use string trim $word \" to clean that up.
If this is a command that you are parsing, use a safe interpreter. Then you can allow Tcl syntax to be used without exposing the guts of your code. I'm pretty sure there are answers here on how to do that already.
Because Tcl doesn't have strong types, the simplest way to do this is to just treat your stdin string like a list of strings. No need to use split to convert a string into a list.
set cmd {"HELLO THERE" 1 2 3}
foreach item $cmd {
puts $item
}
--> HELLO THERE
1
2
3
Use string is list to check if your $cmd string can be treated as a list.
if {[string is list $cmd]} {
puts "Can be a list"
} else {
puts "Cannot be a list"
}

How to split string by numerics

I havetried to split but still failed.
set strdata "34a64323R6662w0332665323020346t534r66662v43037333444533053534a64323R6662w0332665323020346t534r66662v430373334445330535"
puts [split $strdata "3334445330535"] ;#<---- this command does not work
The result needed as below:
{34a64323R6662w0332665323020346t534r66662v43037} {34a64323R6662w0332665323020346t534r66662v43037}
The split command's optional second argument is interpreted as a set of characters to split on, so it really isn't going to do what you want. However, there are other approaches. One of the simpler methods of doing what you want is to use string map to convert the character sequence into a character that isn't in the input data (Unicode is full of those!) and then split on that:
set strdata "34a64323R6662w0332665323020346t534r66662v43037333444533053534a64323R6662w0332665323020346t534r66662v430373334445330535"
set splitterm "3334445330535"
set items [split [string map [list $splitterm "\uFFFF"] $strdata] "\uFFFF"]
foreach i $items {
puts "==> $i"
}
# ==> 34a64323R6662w0332665323020346t534r66662v43037
# ==> 34a64323R6662w0332665323020346t534r66662v43037
# ==> {}
Note that there is a {} (i.e., an empty-string list element) at the end because that's the string that came after the last split element. If you don't want that, add a string trimright between the string map and the split:
# Doing this in steps because the line is a bit long otherwise
set mapped [string map [list $splitterm "\uFFFF"] $strdata]
set trimmed [string trimright $mapped "\uFFFF"]
set items [split $trimmed "\uFFFF"]
The split command doesn't work like that, see the documentation.
Try making the data string into a list like this:
regsub -all 3334445330535 $strdata " "
i.e. replacing the delimiter with a space.
Documentation:
regsub,
split

TCL: Need to delete "(double quotes) from strings in tcl skipping first and last. examples are given below

I need to replace all double quotes from the below string and keep the first and last double quote. How can I do this?
"0 "ifx" "blrcom" "media" "00-00-00-01-01-00" "server" "10.10.10.1" "10.10.10.10" "255.255.255.0" "11.11.11.1" "192.168.1.1" 0 "14.14.14.1"";
The simplest way is probably to remove all double quotes (with string map) and then put the outer ones back on afterwards (with string concatenation).
set str {"0 "ifx" "blrcom" "media" "00-00-00-01-01-00" "server" "10.10.10.1" "10.10.10.10" "255.255.255.0" "11.11.11.1" "192.168.1.1" 0 "14.14.14.1""}
set stripped [string map {\" {}} $str]
set str \"$stripped\"
If you've possibly got that semicolon at the end as well, handle it first/last. string match and string trimright are the right tools.
set gotSemi [string match "*;" $str]
set stripped [string map {\" {}} [string trimright $str ";"]]
set str \"$stripped\"
if {$gotSemi} {
append str ";"
}

TCL command - string trim

I was using the command 'string trimright' to trim my string but I found that this command trims more than required.
My expression is "dssss.dcsss" If I use string trim command to trim the last few characters ".dcsss", it trims the entire string. How can I deal with this?
Command:
set a [string trimright "dcssss.dcsss" ".dcsss"]
puts $a
Intended output:
dcsss
Actual output
""
The string trimright command treats its (optional) last argument as a set of characters to remove (and so .dcsss is the same as sdc. to it), just like string trim and string trimleft do; indeed, string trim is just like using both string trimright and string trimleft in succession. This makes it unsuitable for what you are trying to do; to remove a suffix if it is present, you can use several techniques:
# It looks like we're stripping a filename extension...
puts [file rootname "dcssss.dcsss"]
# Can use a regular expression if we're careful...
puts [regsub {\.dcsss$} "dcssss.dcsss" {}]
# Do everything by hand...
set str "dcssss.dcsss"
if {[string match "*.dcsss" $str]} {
set str [string range $str 0 end-6]
}
puts $str
If what you're doing really is filename manipulation, like it looks like, do use the first of these options. The file command has some really useful commands for working with filenames in a cross-platform manner in it.

TCL : find and remove all characters in a string from the first occurrence of a character in a string

I am a newbie in TCL and in need of a TCL method / utility / code which can find and remove all characters (including itself) in a string from its first occurrence in a string.
I have a string like below:
Func::set()->method();
In the above string I need to find first occurrence of '(' and remove all it and after that so that the resultant string would be just:
Func::set
You can do it with a regular expression:
set the_string [regsub {\(.*} $the_string ""]
or if you're not familiar with regexp then you can do it the more traditional way:
set the_string [
string range $the_string 0 [
expr {[string first "(" $the_string]-1}
]
]
For further info, read the manual pages for [string], [regsub] and [re_syntax].
Another technique is to use split and lindex:
set the_string [lindex [split $the_string "("] 0]
This is short and simple, but may do a lot of extra work if your string is very long.