problem with regexp and catching string

Posted by Mahony on Tue 07 Jun 2016 07:45 AM — 5 posts, 19,343 views.

#0
Hi
I'm trying to catch name from this command and output:


swho 11 20 60
[ 26  Eldar  P+3] [     819 ] Mahony (^\Rhabdo/^)
[ 61  Diva   T+5] [     708 ] *AFK* Trachx <(=Watchmen=)>
[ 54  Eldar  M+5] [     222 ] [Advisor] Nienna [C]
[ 54  Eldar  M+5] [     221 ] *AFK* [Advisor] Xyz [C]
[ 22  Giant  W+7] [       4 ] (HARDCORE) Nightbird /|\Druid/|\
[ 25  Vamp   H+2] [       3 ] (Linkdead) Izabella  


I want to catch the number of gqs (so the %1) and the name. The name position varies depending on the *AFK*, Helper and so on before the name. So it could be %2 or %3 or even %4. I catch only %2 and %3. It is enough for me. But I have problems with it.

The trigger regexp is like this:


match="^\[.{15}\] \[\s+(\d+)\s+\] (.*?) (.*?)"
[ 26  Eldar  P+3] [     819 ] Mahony (^\Rhabdo/^)
%2 is Mahony
%3 is 
[ 51  Vamp   P+6] [     576 ] *AFK* Zetkax 
%2 is *AFK*
%3 is 
[ 54  Eldar  M+5] [     222 ] [Advisor] Nienna [C]
%2 is [Advisor]
%3 is 


Why is the %3 empty? I would expect the rest of the line behind the %2 to be in %3.

What somehow works for me is this match:


match="^\[.{15}\] \[\s+(\d+)\s+\] (.*) (.*)"
[ 26  Eldar  P+3] [     819 ] Mahony (^\Rhabdo/^)
%2 is Mahony
%3 is (^\Rhabdo/^)
[ 61  Diva   T+5] [     708 ] *AFK* Trachx <(=Watchmen=)>
%2 is *AFK* Trachx
%3 is <(=Watchmen=)>


But it is not 100% what I want.

What exactly I want to achieve is this:


[ 61  Diva   T+5] [     708 ] *AFK* Trachx <(=Watchmen=)>
%2 is *AFK*
%3 is  Trachx


What do I do wrong?
Thanks
-Mahony




[EDIT]
Formatting fixed, code tags added, forum codes escaped.
Amended on Tue 07 Jun 2016 07:53 PM by Nick Gammon
USA Global Moderator #1
In a regex pattern [...] means "anything in this set of symbols". [abc] will match either an a, b, or c. [abc]+ will match a, b, c, aa, ab, ac, ba, bb, bc, and so on. If you want to match the [ ] symbols themselves, you need to backslash escape them in the pattern.
#2
Oh crap. The copy/paste didn't work correctly and I didn't notice.
the match is
match="^\[.{15}\] \[\s+(\d+)\s+\] (.*) (.*)"

I see the problem in the end of the match in the (.*) (.*)"

sorry
USA Global Moderator #3
Try this:


^.{20}\s*(\d+)\s\]\s([\*\[\(].+[\*\]\)] )*(\w+)


It should catch the number in %1 and the name in %3
Australia Forum Administrator #4
Here's another way of doing it:


^\[.{15}\] \[\s+(\d+)\s+\](.*?)(?= \w) (\w+)


That starts the same as your original one. Then we have:


(.*?)    --> skip any characters, non greedily
(?= \w)  --> assert (without consuming characters) that we have a space followed by a letter
 (\w+)   --> match the space and capture the name


The lookahead assertion is the important part. The first .*? keeps matching until the assertion is true. That skips words that do not start alone (eg. skips *AFK* / [Advisor] / (Linkdead) ).




Output from your test data:


swho 11 20 60
[ 26  Eldar  P+3] [     819 ] Mahony (^Rhabdo/^)
%1 = 819
%2 = 
%3 = Mahony

[ 61  Diva   T+5] [     708 ] *AFK* Trachx <(=Watchmen=)>
%1 = 708
%2 =  *AFK*
%3 = Trachx

[ 54  Eldar  M+5] [     222 ] [Advisor] Nienna [C]
%1 = 222
%2 =  [Advisor]
%3 = Nienna

[ 54  Eldar  M+5] [     221 ] *AFK* [Advisor] Xyz [C]
%1 = 221
%2 =  *AFK* [Advisor]
%3 = Xyz

[ 22  Giant  W+7] [       4 ] (HARDCORE) Nightbird /|ruid/|
%1 = 4
%2 =  (HARDCORE)
%3 = Nightbird

[ 25  Vamp   H+2] [       3 ] (Linkdead) Izabella  
%1 = 3
%2 =  (Linkdead)
%3 = Izabella