sofista wrote: ↑23 Jul 2022, 10:42
It is not so difficult to accomplish that, but, as mikeyww and I apparently see it, the problem is that it is not as clearly defined as you state.
As I understand it, I would describe the issue as follows: in the exact order stipulated, find the word "yellow" followed by one more characters that do not include the word yellow (1), followed by the word "blue", continued by one or more characters (2) and ended by the word "red" (3).
Some potential problems:
1) The regular expression example uses the symbol "*" - quantifier for more than one or none - but the example string indicates that there are characters, so "+" would be the more appropriate symbol.
2) Same as above. Another issue is that it is not excluded that the word "yellow" may appear between "blue" and "red".
3) It is not indicated whether the characters following the word "red" are relevant or not. It is also not indicated whether the three words are on the same line or whether a multi-line search is required.
Now, ignoring the last two potential problems, to find only the word "yellow" closest to "blue" and "red" I would do it like this:
Code: Select all
str := "yellow3xxxyellow2xxxyellow1xxxbluexxxred1xxxred2xxxred3xxxyellow...."
RegExMatch(str, "yellow(?:(?!yellow).)*?blue.*?red1", m)
MsgBox, % m ; yellow1xxxbluexxxred1
Tested.
thank you very much,
you saw my approach from another approach also successful.
Your code perfectly fulfills my purpose in all the scenarios in which I have tried it.
it always happens to me the same, sometimes for a period, comma, or an exclamation mark I end up reading 7 days in a row, in this case it was for two parenthesis and a period, although I don't remember having seen something similar to your code in the ahk documentation.
Code: Select all
q::
str := "yellow3xxxyellow2xxxyellow1xxxbluexxxred1xxxred2xxxred3xxxyellow....againt...yellow2xxxblue2xxxred2...againt...yellow3xxxblue3xxxred3"
p := 1
array := []
while p:= RegExMatch(str, "yellow(?:(?!yellow).)*?blue.*?red", m, p+StrLen(m))
{
Array[A_Index] := m
msgbox % "Element number " . A_Index . " is " . Array[A_Index]
Count := Array.Count()
}
msgbox, % "count =" Count
return
and it also works in my real scenario: html documents
Code: Select all
q::
content = notvalifirstdhref="validfirsthref="/item/mykeyword-iid-1111111">second href="/item/mykeyword-iid-2222222">
keyword:="mykeyword"
search = href="(?:(?!href=).)*?%keyword%.*?">
p := 1
array := []
while p:= RegExMatch(content, search, m, p+StrLen(m))
{
Array[A_Index] := m ;esto sólo recupera el subpatron
MsgBox, % m
Count := Array.Count()
}
msgbox, % "count =" Count
return
La única forma que encuentro para agradecerte es también compartiendo, si esto te puede ser útil o tienes mejores ideas, te invito a ver este post, con el cual logré mi propósito completo: web scraping con regexmatch en la nube con autohotkey.ahk
viewtopic.php?f=76&t=107135
tema completo: "cómo hacer que las teclas de acceso rápido automático funcionen en la PC a través de conexiones rdp, o que funcionen en escritorios virtuales múltiples, diferentes e independientes sin que los scripts interfieran entre sí".
sometimes I think that ahk in the cloud is the future.
And I definitely learned that approaching an issue from different points of view has a higher chance of success and you get different ways to solve it.
I previously posted a topic asking how to prevent a negative look-ahead (?!....) or negative look-behind (?<!...) from searching the whole string and only taking effect up to a certain word, in this case "red1", since these codes didn't work.
Code: Select all
q::
MsgBox % RegExMatch("xxxxyellow222xxxyellow111yyyyblueñññred111xxxred222againstyellow...", "yellow(?<!.*yellow).*?blue.*?red", SsubPat)
MsgBox, %SsubPat% ; show yellowyyyyblueñññred
return
ñ::
MsgBox % RegExMatch("xxxxyellow222xxxyellow111yyyyblueñññred111xxxred222againstyellow...", "yellow(?!.*yellow).*?blue.*?red", SsubPat)
MsgBox, %SsubPat% ; show yellowyyyyblueñññred
but the forum got too long...
and you solved it and gave me the exact answer on the first try with a yellow(?:(?!yellow).), looking at it from your approach.
finally thanks
see you next time friends...