Jump to content


Photo

Looking for foolproof and elegant solution for checking RE


  • Please log in to reply
3 replies to this topic

#1 SoLong&Thx4AllTheFish

SoLong&Thx4AllTheFish
  • Members
  • 4999 posts

Posted 08 July 2010 - 12:18 PM

I've noted a 'bug' in my TF_Find function (see links in sig if you want to check it)

Situation:

- With TF_Find you can find the linenumbers and/or text of lines containing specific words, the text to search for is a regex

- To speed up the function I've added a quick check at the beginning (see commented line with RegExMatch(Text, SearchText) to see if file or variable contains the RE at all, it not simply return 0 otherwise it would proceed to parse a file on a line by line basis for no good reason

- Now it may happen that if you use the ^ (start of line) option it returns 0 because of course it tries to Match the very first line but because TF_Find operates on a line by line basis that can be inaccurate - see sample list below

- So, just to be sure it tries to find actual lines I have to make sure the m option (multi line) is always passed on in this RegExMatch(Text, SearchText)

- I'm currently testing the code below (red lines) and it seems to work but perhaps fellow AutoHotkey-ers have some other suggestions which may be more fool proof.

list=
(join`r`n
test
test
data1
test
test
data2
test
)

XTF_Find(list,1,0, "is)^data", 0, 1)

XTF_Find(Text, StartLine = 1, EndLine = 0, SearchText = "", ReturnFirst = 1, ReturnText = 0)
	{ ; complete rewrite for 3.1
[color=red]	 If (RegExMatch(SearchText, "^[^)m]*\)") > 0) ; check if m = multiline option is present otherwise it might incorrectly return nul
	 	{
	 	 SearchText:= "m" . SearchText
	 	 MsgBox % SearchText
	 	}[/color]
; If (RegExMatch(Text, SearchText) < 1) ; this I need to "fix"
;	 	Return "0" ; SearchText not in file or error, do nothing
     	
	 ; process text removed	
	}

Suggestions welcome. Note you don't have to use the TF library, the above is enough code to run it...

#2 sinkfaze

sinkfaze
  • Moderators
  • 6089 posts

Posted 08 July 2010 - 05:04 PM

I guess I'm not quite clear on how you're looking to fine tune this function, but is this in the ballpark?

list=
(join`r`n
test
test
data1
test
test
data2
test
)

XTF_Find(list,1,0, "is)^data", 0, 1)

XTF_Find(Text, StartLine = 1, EndLine = 0, SearchText = "", ReturnFirst = 1, ReturnText = 0) {	; complete rewrite for 3.1
	options :=	"^[imsxADJUXPS]+\)"
	If	RegExMatch(SearchText,options,o) {	; check if m = multiline option is present
		SearchText :=	RegExReplace(SearchText,options,(!InStr(o,"m") ? "m$0" : "$0")
	If	!RegExMatch(Text,SearchText)
		Return	False ; SearchText not in file or error, do nothing
}

The thing I'm finding problematic is properly searching for those options with a backtick (`n, `r, `a). It would probably be best to remove any of those options and replace it with (*ANYCRLF) just after the options, but if you can't find it you can't fix it.

#3 SoLong&Thx4AllTheFish

SoLong&Thx4AllTheFish
  • Members
  • 4999 posts

Posted 08 July 2010 - 07:30 PM

The safest method would be to skip the check and always process the file no matter what, which MAY slow things down so not sure what to do. I'll give yours a spin, I can see all sorts of other problems*, not so much the `n as the find is supposed to work on a LINE I don't anticipate such REs in the function nor the user to use them (you can't be idiot proof).

Perhaps simply adding a note with the TF_Find documentation it is advised to always include the m option is the most secure way e.g. leave it up t the user.

* edit: valid RE, but invalid results

list=
(join`r`n
test
test
data a) option 1
tes b)
tes(hello)t
data b) option 2
test
)

MsgBox % XTF_Find(list,1,0, "^\Qdata\E", 0, 1) ; says 0 or false

XTF_Find(Text, StartLine = 1, EndLine = 0, SearchText = "", ReturnFirst = 1, ReturnText = 0) 
{ 
   options :=   "^[imsxADJUXPS]+\)"
   If RegExMatch(SearchText,options,o) 
      SearchText :=   RegExReplace(SearchText,options,(!InStr(o,"m") ? "m$0" : "$0"))
	  MsgBox % SearchText
   If  !RegExMatch(Text,SearchText)
      Return False ; SearchText not in file or error, do nothing
}


#4 sinkfaze

sinkfaze
  • Moderators
  • 6089 posts

Posted 09 July 2010 - 01:53 AM

You'll have to forgive me hugo, I've never had the opportunity to play with your function library so I'm woefully behind the 8-ball on functionality. This seems to be more workable but may not meet the needs of your additional parameters:

list=
(join`r`n
test
test
data a) option 1
tes b)
tes(hello)t
data b) option 2
test
)

MsgBox %	XTF_Find(list,1,0, "^\Qdata\E", 0, 1)

XTF_Find(text,startLine=1,endLine=0,searchText="",returnFirst=1,returnText=0)
{
	options :=	"^[imsxADJUXPS]+\)"
	if	RegExMatch(searchText,options,o)
		searchText :=   RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0(*ANYCRLF)" : "$0"))
	else	searchText :=	"m)(*ANYCRLF)" searchText
	MsgBox %	searchText
	return	!RegExMatch(Text,searchText) ? False : True
}