Robin Hsu
Robin Hsu

Reputation: 4504

Tcl: Removing the pound sign commented line

Why can't I remove the pound sign commented line?

#!/usr/bin/tclsh

set lines [list file1.bmp {  # file2.bmp} file3.bmp ]

# Now we apply the substitution to get a subst-string that
# will perform the computational parts of the conversion.
set out [regsub -all -line {^\s*#.*$} $lines {}]

puts $out

Output:

file1.bmp {  # file2.bmp} file3.bmp

-UPDATE-

Expected output:

file1.bmp {} file3.bmp

{} means empty string.

In fact, it's my first step. My ultimate goal is to eliminating all commented line and all empty lines. The above question only changes all comment lines into empty lines. For example, if the input is:

set lines [list file1.bmp {  # file2.bmp} {} file3.bmp ]

I want my ultimate results to be

file1.bmp file3.bmp

Note: Stackoverflow mistakenly dim everything from and after the pound (#) sign, thinking that those are comments. Yet in TCL syntax, it should not be comments.

@Tensibai: I also want to remove empty lines, thus I match any number of spaces before '#'. (since after removing all following '#' included, it's an empty line). In fact, in my data, the comment always appears as a full line by itself. Yet the '#' sign may not appear at the 1st character => the spaces can leads a comment line.

Upvotes: 1

Views: 1114

Answers (1)

Tensibai
Tensibai

Reputation: 15784

Edit to answer after edit:

#!/usr/bin/tclsh

set lines [list file1.bmp { # file2.bmp } file3.bmp #test ]
puts $lines
# Now we apply the substitution to get a subst-string that
# will perform the computational parts of the conversion.
set out [lsearch -regexp -all -inline -not $lines {^\s*(#.*)?$}]

puts $out

Output:

file1.bmp file3.bmp

You're working on a list, the representation of a list is a simple text so you can regsub it, but it's a single line. If you want to check elements on this list you have to use list related commands.

Here lsearch will do what you wich, checking each item to see if they match the regex, the -not tells to return the elements no matching with -all -inline


Old answer:

Why: because your regex match any pound preceded only by 0 or unlimited number of spaces. Thus it will only match comment lines and not inline comments.

Have a look to http://regex101.com to test regexes.

A working regex would be:

#!/usr/bin/tclsh

set lines [list file1.bmp {  # file2.bmp} file3.bmp ]

# Now we apply the substitution to get a subst-string that
# will perform the computational parts of the conversion.
set out [regsub -all -line {^(.*?)#.*$} $lines {\1}]

puts $out

For the regex (complete details here):

  • ^ Matches start of line
  • (.*?)# Matches and capture as limited number of chars as possible before the # (non greedy operator ? to limit the match)
  • .*$ matches any numbe of chars until end of line

And we replace with \1 which is the first capture group (and the only one in this case).

Output:

file1.bmp {

This will also remove full line comments but may leave spaces or tabs if there's some before the pound sign and so leave blank lines.

Upvotes: 2

Related Questions