1

Hi, I am trying to extract an engine from a String, which has proven my test (hold). In the example bellow, my output should be proengine2.

engine1 {status fail reason checked depth 0 } engine2 {status fail reason checked depth 0 } proengine1 {status open reason checked depth 0 } **proengine2** {status **hold** reason checked depth 1 }

Any idea how to do that with Tcl or regular expression?

Thanks, Sasa

Clad Clad
  • 2,217
  • 1
  • 15
  • 30
  • what did you try yet ? – Clad Clad Apr 10 '14 at 10:35
  • FYI: The official documentation for the [Tcl `regexp` command](http://wiki.tcl.tk/986) and its [manpage](http://www.tcl.tk/man/tcl8.4/TclCmd/regexp.htm), are found in the [Stack Overflow Regular Expressions FAQ](http://stackoverflow.com/a/22944075/2736496), listed under "Flavor-Specific Information". Once you are ready, you can try it out in one of the online regex testers, as listed in the bottom section. – aliteralmind Apr 10 '14 at 17:18

3 Answers3

1

If you want to get the engine with status hold, try something like this:

regexp -- {([^\}[:blank:]]+?)\s*?\{status hold} $data - engine

Your engine will be in the $engine variable.

([^\}[:blank:]]+?) will match non } or blank characters (this is where the engine name is matched) and stored into the first submatch, engine, provided the next parts match, meaning any spaces \s*? and {status hold.

If you have multiple engines you might try something like that:

set engines [regexp -all -inline -- {[^\}[:blank:]]+?(?=\s*?\{status hold)} $data]

Where $engines will be a list of all engines on hold.

Here, I'm using a positive lookahead instead of capture groups because -all -inline will return a list of all matches and sub-matches. The regex is about the same, with the first pair of () removed and the second part wrapped around (?= ... ) (which is the positive lookahead).

Jerry
  • 67,172
  • 12
  • 92
  • 128
  • @user3518939 Awesome! Feel free to [accept my answer](http://meta.stackexchange.com/a/5235/192545) ^^ – Jerry Apr 10 '14 at 14:03
0

Hi there here is a solution if the one with the **hold** always have the stars around as hold. Here is the code :

    String test = "engine1 {status fail reason checked depth 0 } engine2 {status fail reason checked depth 0 } proengine1 {status open reason checked depth 0 } **proengine2** {status **hold** reason checked depth 1 }";
    System.out.println(test.replaceAll(".*\\}\\s\\*{2}(.*)\\*{2}\\s\\{.*", "$1"));

output : proengine2

Clad Clad
  • 2,217
  • 1
  • 15
  • 30
  • Thanks!!!In my tool with Tcl interpreter I got: extra characters after close-quote while executing "regexp System.out.println(test.replaceAll(".*\\}\\s\\*{2}(.*)\\*{2}\\s\\{.*", "$1")" Where did you test this? – user3518939 Apr 10 '14 at 11:30
  • I tested this in Java if it's the question ^^ – Clad Clad Apr 10 '14 at 12:03
0

Your data is fortunately formatted like a Tcl dictionary, so:

set s {
engine1 {status fail reason checked depth 0 } engine2 {status fail reason checked depth 0 } 
proengine1 {status open reason checked depth 0 } proengine2 {status hold reason checked depth 1 }
}

set d [dict create {*}$s]
dict for {key info} $d {
    if {[dict get $info status] eq "hold"} {
        puts $key
    }
}

outputs

proengine2

http://tcl.tk/man/tcl8.5/TclCmd/dict.htm

glenn jackman
  • 207,528
  • 33
  • 187
  • 305