Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Put here requests of problems with regular expressions


  • Please log in to reply
1074 replies to this topic
azure
  • Members
  • 1216 posts
  • Last active: Mar 18 2015 09:06 AM
  • Joined: 07 Jun 2007

..why the code:
NewStr := RegExReplace( Haystack, "(?!^(" list "))")
does not work?

No insult intended but its probably your needle.
AFAICT your testing a negative look-ahead against nothing.

Please post all or part of your haystack ( with matches ).


my haystack is:
2342	11 04 9120	3
3942	11 03 0342	5
9524	11 22 1203	4
2313	11 21 3943	0
9422	11 39 3992	2
my list is:
3942
2313

my script is:
Fileread, list, list.txt
stringreplace, list, list, `r`n, |, all
Fileread, asd, haystack.txt
NewStr := RegExReplace( asd, "(?!^(" list "))")
Msgbox % NewStr

the NewStr should be:
2342   11 04 9120   3 

9524   11 22 1203   4 

9422   11 39 3992   2

but it is the same as my haystack

TLM
  • Administrators
  • 3864 posts
  • Last active:
  • Joined: 21 Aug 2006
This seems to work for me
fileread, list, list.txt
fileread, hStack, haystack.txt

ndl:=subStr( (rStr:=regexReplace( list, "\r\n|$", ".*|" )), 1, strLen( rStr )-1 )
msgbox % nStr:=regexReplace( hStack, "`a)" ndl )
Note, this will only work when the values are read from files!
To get the same thing from values read directly from variables in the script use:
ndl:=subStr( (rStr:=regexReplace( list, "[color=red]`n[/color]|$", ".*|" )), 1, strLen( rStr )-1 )
hth

dirty bit
[color=grey]loop 2
  fileread, val%a_index%, % ( i:=!i ? "list" : "haystack" ) ".txt"[/color]

Posted Image

don't duplicate, iterate!


azure
  • Members
  • 1216 posts
  • Last active: Mar 18 2015 09:06 AM
  • Joined: 07 Jun 2007
it works very well, thanks!

regexReplace( hStack, "`a)" ndl )


in the above command, you search for `a) and you replace it with ndl

ndl is supposed to be 3942|2313, according to:
regexReplace( list, "\r\n|$", ".*|" )), 1, strLen( rStr )-1 )

what `a) is exactly? I know ` works as an escape character (although I am not sure if it works like that in AHK language AND in regex, since afaik escape in regex is \)

leehong1
  • Validating
  • 403 posts
  • Last active: Aug 11 2016 11:25 AM
  • Joined: 24 Nov 2008
TLM...your code do extraxt all the data.....but i need each set of data separately send to a GUI EDIT box.....

leehong1
  • Validating
  • 403 posts
  • Last active: Aug 11 2016 11:25 AM
  • Joined: 24 Nov 2008
well ...TLM again has help me out here....http://www.autohotke...pic.php?t=79302

TLM
  • Administrators
  • 3864 posts
  • Last active:
  • Joined: 21 Aug 2006
Practicing nested assertions like
(?<=(?<!foo)bar)baz
; matches an occurrence of "baz" that is preceded by "bar"
; which in turn is not preceded by "foo"
Got any challenging ones I can solve??
ty

Posted Image

don't duplicate, iterate!


Gogo
  • Guests
  • Last active:
  • Joined: --
Here is a task
How to remove 'cat' from a multi-line string but only if there is no 'dog' before it on the same line.
Text =
(
This [color=red]cat [/color]must go away
Here is a [color=red]dog[/color] so this [color=red]cat[/color] must remain
)

MsgBox % RegExReplace(Text,"m`a)cat")


Odlanir
  • Members
  • 775 posts
  • Last active: Mar 06 2014 11:02 AM
  • Joined: 07 Aug 2011
Gogo, seems this don't works. I've cut and paste the msgbox contents.

---------------------------
~temp.ahk
---------------------------
This must go away
Here is a dog so this must remain
---------------------------
OK
---------------------------


Win7 - Firefox 10.0.2 - AHK_L 1.1.07.00
Please bear with me and my English which is so bad at times that even I don't understand myself

Gogo
  • Guests
  • Last active:
  • Joined: --
It doesn't work, indeed. I need working one.

I found a solution "dog.*\K|cat" but can't use it because I actually need to replace the 'cat' with a 'fish'.
And something else: There can be more than one 'cat' on a line.

Gogo
  • Guests
  • Last active:
  • Joined: --
It was hard for me but I succeeded. Here is a working RegEx.
The RegEx matches any occurrence of 'cat' but only if there is no 'dog' before it in the same line.
Text =
(
This [color=red]cat[/color] must become a fish.
These [color=red]cat[/color] and [color=red]cat[/color] too. This is a [color=red]dog[/color] so this [color=red]cat[/color] must remain a [color=red]cat[/color].
)
MsgBox % RegExReplace(Text, "m`a)(^|\G)(?>.*?(?=cat|dog))\Kcat" ,"fish")


sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008
Would you mind explaining how it works?

Gogo
  • Guests
  • Last active:
  • Joined: --
Starting from the core:

^.*?(cat|dog) - this pattern will find the first occurrence of 'cat' or 'dog' in the line. The anchor ^ and the lazy star *? ensure us that this is really the first cat or dog. We want to match only cats so we should add a look-behind (?<=cat) to check what animal we have found.

^.*?(cat|dog)(?<=cat) - we can get rid of the look-behind if set the (cat|dog) group as look-ahead

^.*?(?=cat|dog)cat - this pattern should find the first animal in the line and report a match only if it's a cat. Unfortunately if the match fails RegEx backtracks to the lazy star *? continues searching and finds the next animal in the line (actually jumps over the dog). To prevent backtracking we can use atomic grouping (?>group)

http://www.regular-e...nfo/atomic.html
An atomic group is a group that, when the regex engine exits from it, automatically throws away all backtracking positions remembered by any tokens inside the group.


^(?>.*?(?=cat|dog))cat - now RegEx finds the first animal in the line and report match only if it's a 'cat' but reports all characters before the cat too. To discard them and make RegEx to report only 'cat' we can use \K.

^(?>.*?(?=cat|dog))\Kcat - this pattern will find only the first cat because is anchored to the start of the line ^. to match next cat in the line we have to add \G-anchor as an alternative to the ^ anchor (^|\G)
\G anchor points the end of the last successful match. With this alternative RegEx will match the first cat in the line^ or| the first cat after the last matched cat \G.

Finally the pattern looks like this:
m`a)(^|\G)(?>.*?(?=cat|dog))\Kcat - m`a) are options and are explained in Help/Index/RegEx:Quick Reference

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
Wow. :shock:
I actually tried to find a solution but failed :(

glad you found a solution; too bad it couldn't be simpler ;)

TLM
  • Administrators
  • 3864 posts
  • Last active:
  • Joined: 21 Aug 2006
Yea my 1st attempt was a cheat
regexReplace( Text, "s)\scat(?=.*dog)" )
In the end, I was stump'd..

And something else: There can be more than one 'cat' on a line.

Posted Image

Looking at the solution, I dont feel as fail now tho :shock: lolol

Brilliant challenge BTW Gogo

Posted Image

don't duplicate, iterate!


Odlanir
  • Members
  • 775 posts
  • Last active: Mar 06 2014 11:02 AM
  • Joined: 07 Aug 2011
I would like to put every coord/size value in Gui,Add command in a 3 digit field padded with 0, so this:
Gui,Add,Button,x9 y9 w100 h30,Button1
Gui,Add,Button,x109 y9 w10 h30,Button2
Gui,Add,Button,x9 y49 w70 h30,Button3
should became this
Gui,Add,Button,x009 y009 w100 h030,Button1
Gui,Add,Button,x109 y009 w010 h030,Button2
Gui,Add,Button,x009 y049 w070 h030,Button3
I've tried the code below and it works for 1 digit ( hardcoding two 0 in the replace string), but how can I make it work for an arbitrary number of digit?
str 	:= ""
loop, parse, Clipboard, `n,`r
{
	if (RegExMatch(A_LoopField, ".*Gui\b.*Add\b.*"))
		str .= RegExReplace(A_LoopField, "i)\b(x|y|w|h)(\d)\b","$1[color=red]00[/color]$2") "`n"
	else
		str .= A_LoopField "`n"
}
clipboard := str
ExitApp

Win7 - Firefox 10.0.2 - AHK_L 1.1.07.00
Please bear with me and my English which is so bad at times that even I don't understand myself