Gert Gottschalk
Gert Gottschalk

Reputation: 1716

Regexp in TCL to parse out string prior to last matching character

In a TCL script I have a objects with string values like:

ab_cde_12-3_xyz
def_5&6_hjk
zzz_1@234

I need to extract the substrings prior to (but not including) the last '_'.

I have tried :

regexp -all -inline {(.*)(?=_)} $my_string

But it gives extra garbage which I don't need.

Is there a cleaner way to do this?

Thanks, Gert

Upvotes: 1

Views: 3421

Answers (3)

Johannes Kuhn
Johannes Kuhn

Reputation: 15163

Ok, there are 3 ways to do that:

  • Match everything until _ followed by no other _:

    regexp {^(.*)_[^_]*$} $my_string -> data
    
  • Replace the last part with an empty string:

    regsub {_[^_]*$} $my_string {}
    
  • Get the substring of your string up until the last _

    string range $my_string 0 [string last _ $my_string]-1
    

    This only works if the string has an _, otherwise I suggest

    expr {[set pos [string last _ $my_string]] != -1
          ? [string range $my_string 0 ${pos}-1]
          : $my_string}
    

Upvotes: 4

glenn jackman
glenn jackman

Reputation: 246807

You don't actually need a regular expression for this: list operations will do fine:

set new [join [lrange [split $my_string _] 0 end-1] _]

Upvotes: 0

Explosion Pills
Explosion Pills

Reputation: 191749

Use:

(.*)_[^_]*$

This is "everything up to a _ followed by zero or more non-_ characters followed by the end of the string." This ensures that it is the last underscore.

Upvotes: 0

Related Questions