0

How to take the word 'healthcare' from the word 'vendor_reg_analysis_healthcare.xls', By using the regular expression command SO by telling in detail , I need to take a word after third _ from the whole name and before dot. so that I can get the name 'healthcare' from the 'vendor_reg_analysis_healthcare.xls'

2
  • @Prataap Singh : Please add more details to your question. Add proper tags also. Sep 17, 2014 at 4:26
  • @RenjuChandranchingath What more detail do you want him to add? seems pretty clear to me
    – barlop
    Sep 17, 2014 at 17:37

3 Answers 3

2

What tool are you using for your regular expression?

In very general terms, I would think one of the following might work as a matching expression:

.*_([^_]*)\..*

You would then have things in "capture" number one.

For example in perl, this might be:

$s = "vendor_reg_analysis_healthcare.xls";
$s =~ /.*_([^_]*)\..*/;
print $1, "\n";

Or, if you want to modify $s in place:

$s =~ s/.*_([^_]*)\..*/$1/;

Now, $s would contain "healthcare".

So... The above expression would capture specifically the last thing after _ and before .. If the number of _'s is variable, this may or may not be what you want. For example, if you had no underscores, this would fail to match. Or if you had 4, and wanted the underscore that occurred after the 3rd one to still be part of the resulting string, this would be wrong, as well.

Also, depending on the regular expression engine you're using, you may or may not need to use backslashes before the parentheses, as such:

.*_\([^_]*\)\..*

e.g. with sed (as mentioned in another answer, though you mention Windows, so I'm guessing this isn't your tool of choice):

echo vendor_reg_analysis_healthcare.xls | sed -e 's/.*_\([^_]*\)\..*/\1/'

Anyway, does this get you what you need? If not, please elaborate on what context (engine, software program, whatever) your regular expressions are being run in (is "SO" a piece of software? I didn't know what that part of your post meant), and/or more concrete details of what you're looking for.

And for what it's worth, here are the parts of the above expression, broken down:

  • .* - gobble up as many characters as you can (zero to many (*) of any character(.))
  • _ - that are followed by an underscore
  • ( - begin to capture
  • [^_]* - capturing zero to many non-underscore characters ([ to ] define a character class, which is not (^) an underscore; then zero to many (*) of those)
  • ) - end capture
  • \. - followed by a literal period
  • .* - followed by zero to many more arbitrary characters

You could adjust components of this appropriately if that's not exactly what you want.

2
  • Note: the character class I have in here is probably not strictly necessary (just matching .*_(.*)\..* would get you the same thing here). I figure it's useful for understanding, though, and/or if other parts of the expression get changed for whatever reason, it might avoid a situation wherein that other change might break this. One could also (instead) get rid of the _ before that, if you have a regex engine that supports non-greedy matching, like so: .*?([^_]*)\..*. Just depends on what you want, exactly.
    – lindes-hw
    Sep 18, 2014 at 1:41
  • 1
    re "non-greedy matching" The term for that *? or +? is lazy.. Interestingly there is a third type of quantifier, called 'possessive' regular-expressions.info/possessive.html stackoverflow.com/questions/5319840/…
    – barlop
    Sep 18, 2014 at 6:18
0

Using Ubuntu Linux I created a file with the same name and then used the following commands piped together to display just the word 'healthcare'.

vagrant@dev:~$ ls vendor_reg_analysis_healthcare.xls | sed -e s/_/./g |  cut -d '.' -f4
healthcare

The ls command "lists" the filename vendor_reg_analysis_healthcare.xls. From here we pipe the output of ls to sed and replace every instance of the underscore with a period. Why? Because now we can use the . as a common delimeter, so when we pass the new filename of vendor.reg.analysis.healthcare.xls to the cut command we now say "cut everything except the fourth field" which is the word healthcare.

Hope this helps!

2
  • and worth noting he can use gnuwin32 in windows, to get those commands
    – barlop
    Sep 17, 2014 at 17:38
  • your command works but also maybe worth noting `$ echo vendor_reg_analysis_healthcare.xls | cut -d '_' -f4 <-- even without a regex.. woudl almost be there just has .xls at the end giving healthcare.xls
    – barlop
    Sep 17, 2014 at 18:01
0
.*_(.*)\..*    <--- an 11 char regex 


$echo vendor_reg_analysis_healthcare.xls|sed -r "s/.*_(.*)\..*/\1/"
healthcare

You have to match the whole thing and capture the part you want. So you have to match the whole thing in such a way that you split it just so to get what you want.

.*_ will match everything it can then try with that to have an _ after it. So the .* will eat up many underscores too. But not the last one. Because the _ after it must match an underscore. So that matches vendor_reg_analysis_

Now you have matched up to just before 'healthcare.xls' This part

(.*)\..*

says capture everything up to just before a literal dot, and capture that. Then match the rest. (.*)

This regex .*_([^.]*).* would also work, i'm not sure if it's faster, but it's 12 characters, so one character longer.

Not the answer you're looking for? Browse other questions tagged .