• A behaviour of regexp I cannot understand

    From Olivier@[email protected] to comp.lang.tcl on Wed Oct 14 15:05:52 2026
    From Newsgroup: comp.lang.tcl


    Hello,

    Simply :

    set _res [regexp -inline -all {\S+} "dum dummy a b c d c4"]

    gives a list of 7 items : dum dummy a b c d c4

    set _res [regexp -inline -all {c+} "dum dummy a b c d c4"]

    gives a list of " items : c c

    I understand that {c+} acts as a specification, but I cannot understand why {\S+}
    acts as a counter-specification, it should return only spaces and/or tabs ?

    I found this "trick" on https://wiki.tcl-lang.org/page/Get+a+Certain+Line+From+a+File
    I often deal with simulation data where items of line are homogeneously separated
    either by space or by tab. So the line can be considered as a list. But in rare case
    you stumble on hybrid separators : line defining units or names for instance, that is
    how I came to this question. And this "trick" works as a charm !

    Olivier.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Erik Leunissen@[email protected] to comp.lang.tcl on Wed Oct 14 20:08:51 2026
    From Newsgroup: comp.lang.tcl

    On 10/14/26 17:05, Olivier wrote:
    regexp -inline -all {\S+} "dum dummy a b c d c4"

    Did you mean to do:

    regexp -inline -all {\s+} "dum dummy a b c d c4"

    Note the lower case character "s".

    Erik Leunissen
    --
    elns@ nl | Merge the left part of these two lines into one,
    xs4all. | respecting a character's position in a line.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Olivier@[email protected] to comp.lang.tcl on Wed Oct 14 19:03:11 2026
    From Newsgroup: comp.lang.tcl


    Erik Leunissen <[email protected]> posted:

    On 10/14/26 17:05, Olivier wrote:
    regexp -inline -all {\S+} "dum dummy a b c d c4"

    Did you mean to do:

    regexp -inline -all {\s+} "dum dummy a b c d c4"

    Note the lower case character "s".

    Erik Leunissen

    Ah ! Thank you, your message makes me look (again) at the definition of \S with an uppercase : \S <==> [^[:space:]] . I did not pay attention to the "^" wich means :
    "If the list begins with “^”, it matches any single character (but see below) not from the rest of the list."

    The behaviour is now obvious ! It was in the documentation, but I had in mind that "^"
    was relative to the "beginning of", not that usage.

    Thanks for your time,

    Olivier.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Rich@[email protected] to comp.lang.tcl on Wed Oct 14 19:21:58 2026
    From Newsgroup: comp.lang.tcl

    Olivier <[email protected]d> wrote:

    Hello,

    Simply :

    set _res [regexp -inline -all {\S+} "dum dummy a b c d c4"]

    \S is a special symbol, it is documented in the re_syntax man page
    under the "CLASS-SHORTHAND ESCAPES" header:

    \S [^[:space:]]

    So using \S is the same as having entered [^[:space:]] into the regex.
    And that [^[:space:]] means "any character that is not in the set
    ":space:" (whitespace). Or shorter: "not whitespace characters".

    "+" in a regex means one or more matches of the prior atom (in this
    instance the shorthand for "[^[:space:]]".

    So \S+ means one or more characters that are not whitespace characters.

    Which is why you get this result:

    gives a list of 7 items : dum dummy a b c d c4

    set _res [regexp -inline -all {c+} "dum dummy a b c d c4"]

    "c" is just a regular character. So it means "c". + means one or more
    of the prior atom (the "c") so it means a run of one or more c
    characters. You have two runs of "c" characters, both one character
    long. The lone "c" and the "c4". So this result also makes perfect
    sense:

    gives a list of " items : c c

    I understand that {c+} acts as a specification, but I cannot understand why {\S+}
    acts as a counter-specification, it should return only spaces and/or tabs ?

    /S+ (the capitolized variety) is already a "not" specifier by
    definition. So it is "not whitespace" which is why you get everything
    but the white space. You may be thinking of \s which is shorthand for [[:space:]]
    which is "all white space characters".

    I found this "trick" on https://wiki.tcl-lang.org/page/Get+a+Certain+Line+From+a+File I often
    deal with simulation data where items of line are homogeneously
    separated either by space or by tab. So the line can be considered
    as a list. But in rare case you stumble on hybrid separators : line defining units or names for instance, that is how I came to this
    question. And this "trick" works as a charm !

    Yes, it's a useful "trick" to normalize a set of "white space
    separatated items" into a list, when you don't care how many white
    space separaters there are, or which exact white space characters are
    present.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Rich@[email protected] to comp.lang.tcl on Wed Oct 14 19:46:25 2026
    From Newsgroup: comp.lang.tcl

    Olivier <[email protected]d> wrote:

    Erik Leunissen <[email protected]> posted:

    On 10/14/26 17:05, Olivier wrote:
    regexp -inline -all {\S+} "dum dummy a b c d c4"

    Did you mean to do:

    regexp -inline -all {\s+} "dum dummy a b c d c4"

    Note the lower case character "s".

    Erik Leunissen

    Ah ! Thank you, your message makes me look (again) at the definition
    of \S with an uppercase : \S <==> [^[:space:]] . I did not pay
    attention to the "^" wich means : "If the list begins with “^”, it matches any single character (but see below) not from the rest of the
    list."

    The behaviour is now obvious ! It was in the documentation, but I
    had in mind that "^" was relative to the "beginning of", not that
    usage.

    Sadly, ^ does double duty in regular expressions. It is an anchor,
    when used outside bracket expressions ([]) and it is the negation
    operator when used inside bracket expressions, but then, only if it is
    the first character in the bracket expression, otherwise it is just
    itself if it occurs elsewhere in brackets.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Olivier@[email protected] to comp.lang.tcl on Thu Oct 15 09:09:06 2026
    From Newsgroup: comp.lang.tcl


    Rich <[email protected]d> posted:


    Yes, it's a useful "trick" to normalize a set of "white space
    separatated items" into a list, when you don't care how many white
    space separaters there are, or which exact white space characters are present.

    Thank you, your answer came simultaneously when I finally understood
    when coming back to the documentation after Erik's
    answer. I would say that your explanation is somewhat exhaustive.

    The devil is in the details, and in Tcl/Tk documentation there are a lot.

    Olivier.

    PS : I read your explanation twice, not to forget that "^" !
    --- Synchronet 3.22a-Linux NewsLink 1.2