AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Help with Regex - Last Match in string

 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Tyrsius



Joined: 09 Jul 2009
Posts: 140

PostPosted: Tue Jan 12, 2010 12:25 am    Post subject: Help with Regex - Last Match in string Reply with quote

I have a temporary solution to this problem, but I believe it to be wasteful and am hoping a better solution exists. What I think the answer should be is a RegExMatch that grabs only the last pattern in a string.

I have a (potentially) long body of text with a template in it, and I want to match parts of the template. It is likely that this template will appear more than once in the text, and I want to only match the LAST instance of this template.

The Template (and Match target):
* Operator's name: - $$$$$$$$$$
* Equipment model: - $$$$$$$$$
* Reported Issues: - $$$$$$$$$$

The $'s are the pieces I want to match. Really, it just needs to match to the end of the line after the dash (-), which may be more than one word (often, on the reported issues, it is a full sentence). If there is a better method for matching to the end of the current line I would also be interested in learning that.

The code so far (poor, I know)
Code:

loop, parse, T_Description, `n
      {
      if not (RegExMatch(A_Loopfield, "(\* Operator's name: - )\K.*")=0)
         {
         RegExMatch(A_Loopfield, "(\* Operator's name: - )\K.*", Sum1)
         }
      else if not (RegExMatch(A_Loopfield, "(\* Equipment model: - )\K.*")=0)
         {
         RegExMatch(A_Loopfield, "(\* Equipment model: - )\K.*", Sum2)
         }
      else if not (RegExMatch(A_Loopfield, "(\* Reported Issues: - )\K.*")=0)
         {
         RegExMatch(A_Loopfield, "(\* Reported Issues: - )\K.*", Sum3)
         }
      }


I know I don't need the brackets on the one-line if-statements, but I don't like the way it looks with just a tab. Sorry if that makes it cluttered.

I have tried negative look-aheads with dotall enabled, but I can't get them to work properly in AHK or Gskinner (a popular browser-based regex tester). Instead of matching the last instance it grabs the first match and EVERYTHING after it.

I am interested in anything that is more efficient than a parsing loop, but because I already have a working solution I am much more intersted in figuring out the general solution of finding the last match of a pattern.

If this thread has already been made, I couldn't find it (I looked... hard), and I am sorry for duplicating.

Note: I have tested with a look-behind, I only used \K because it was shorter. They both work,
Back to top
View user's profile Send private message
Peter



Joined: 30 Dec 2005
Posts: 448

PostPosted: Tue Jan 12, 2010 7:45 am    Post subject: Reply with quote

Tyrsius wrote:
The $'s are the pieces I want to match. Really, it just needs to match to the end of the line after the dash (-)
I'm far from an RegEx expert, so maybe wrong suggestion, but is this useful?:
AHK Help file wrote:
^ $ :
$ may appear at the end of a pattern to require the match to occur at the very end of a line.
Back to top
View user's profile Send private message
sinkfaze



Joined: 18 Mar 2008
Posts: 5044
Location: the tunnel(?=light)

PostPosted: Tue Jan 12, 2010 3:09 pm    Post subject: Reply with quote

Is this what you're looking for?

Code:
var=
(
* Operator's name: - here's some text I want
* Operator's ext: but I don't want this
* Equipment model: - here's some more text I want
* Equipment make: but not this
* Reported Issues: - and here's the last bit of text
)
Loop, Parse, var, `n
{
  if RegExMatch(A_LoopField,".* - ")
    res.=((A_Index=1) ? "" : "`n") RegExReplace(A_LoopField,".* - ")
}
MsgBox % res

_________________
Try Quick Search for Autohotkey or see the tutorial for newbies.
Back to top
View user's profile Send private message Send e-mail
HotKeyIt



Joined: 18 Jun 2008
Posts: 4652
Location: AHK Forum

PostPosted: Tue Jan 12, 2010 4:07 pm    Post subject: Reply with quote

and here's the last bit Smile
Code:
var=
(
* Operator's name: - here's some - text I want
* Operator's ext: but I don't want - this
* Equipment model: - here's some more - text I want
* Equipment make: but not this
* Reported Issues: - and here's the last bit - of text
)
res:=RegExReplace(var,"^.*:\s-\s|\s-\s.*$","",0)
MsgBox % res

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun Wink
Back to top
View user's profile Send private message
Tyrsius



Joined: 09 Jul 2009
Posts: 140

PostPosted: Tue Jan 12, 2010 7:01 pm    Post subject: Reply with quote

Neither of those work, but I think you guys misunderstood. The template I listed doesn't have other lines in between the ones I want, it appears exactly as I listed it. It just appears multiple times, in its entirety.

Like this.

Code:


 * Operator's name: - 1a
 * Equipment model: - 1b
 * Reported Issues: - 1c

 * Operator's name: - 2a
 * Equipment model: - 2b
 * Reported Issues: - 2c

 * Operator's name: - 3a
 * Equipment model: - 3b
 * Reported Issues: - 3c



When I run this function, it needs to report back

Code:

var1=3a
var2=3b
var3=3c


I hope that clears it up.
Back to top
View user's profile Send private message
jaco0646



Joined: 07 Oct 2006
Posts: 3113
Location: MN, USA

PostPosted: Tue Jan 12, 2010 11:52 pm    Post subject: Reply with quote

RegEx is usually a last resort for me. I start by looking for a simpler method. Wink
Code:
var =
(
 * Operator's name: - 1a
 * Equipment model: - 1b
 * Reported Issues: - 1c

 * Operator's name: - 2a
 * Equipment model: - 2b
 * Reported Issues: - 2c

 * Operator's name: - 3a
 * Equipment model: - 3b
 * Reported Issues: - 3c
)

Loop, Parse, var, `n, `r
 var1:=var2, var2:=var3, var3:=SubStr(A_LoopField,-1)
MsgBox,% "var1 = " var1 "`nvar2 = " var2 "`nvar3 = " var3


EDIT: Here's a RegEx anyway. Razz
Code:
input =
(
 * Operator's name: - 1a
 * Equipment model: - 1b
 * Reported Issues: - 1c

 * Operator's name: - 2a
 * Equipment model: - 2b
 * Reported Issues: - 2c

 * Operator's name: - 3a
 * Equipment model: - 3b
 * Reported Issues: - 3c
)

RegExMatch(input,".*: - (\d\w)\R.+: - (\d\w)\R.+: - (\d\w)$",var)
MsgBox,% "var1 = " var1 "`nvar2 = " var2 "`nvar3 = " var3
Back to top
View user's profile Send private message Visit poster's website
Tyrsius



Joined: 09 Jul 2009
Posts: 140

PostPosted: Wed Jan 13, 2010 1:27 am    Post subject: Reply with quote

The problem is the template (and therefore the text I am looking for) is not going to be the end of the string, so grabbing the last three lines is not going to get the output needed.

I still think a RegEx for finding the last instance of a pattern in a multi-line string is going to be the best way of finding this, given that there are variables in what the string contains.

Does anyone know how to accomplish this in AHK?
Back to top
View user's profile Send private message
jaco0646



Joined: 07 Oct 2006
Posts: 3113
Location: MN, USA

PostPosted: Wed Jan 13, 2010 2:58 am    Post subject: Reply with quote

Tyrsius wrote:
it appears exactly as I listed it. It just appears multiple times, in its entirety.
I thought this meant there was no more text after the pattern, sorry about that. Here's one that seems to work, in that case.
Code:
input =
(
 Other text may be here.

 * Operator's name: - 1a
 * Equipment model: - 1b
 * Reported Issues: - 1c

 * Operator's name: - 2a
 * Equipment model: - 2b
 * Reported Issues: - 2c

 * Operator's name: - 3a
 * Equipment model: - 3b
 * Reported Issues: - 3c

 Other text may be here.
)

RegExMatch(input,".*: - (.+?)\R.+?: - (.+?)\R.+?: - (.+?)(\R|$)",var)
MsgBox,% "var1 = " var1 "`nvar2 = " var2 "`nvar3 = " var3
...whether it's more efficient than a parsing loop, I don't know.
Back to top
View user's profile Send private message Visit poster's website
Tyrsius



Joined: 09 Jul 2009
Posts: 140

PostPosted: Wed Jan 13, 2010 7:42 pm    Post subject: Reply with quote

jaco0646 wrote:
Tyrsius wrote:
it appears exactly as I listed it. It just appears multiple times, in its entirety.
I thought this meant there was no more text after the pattern, sorry about that.


I think I was just failing to be clear. I said that because other people where adding lines inbetween the ones I listed, so I was trying to clarify that that wouldn't happen. I Just went to far in the other direction.

Thanks though, that code seems to work.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group