mary Posted September 24, 2006 Share Posted September 24, 2006 Hi !imagine that you parse a javascript code and you want to catch all arguments of a given function. my first idea is to use StringSplit ( $fucntion_definition_line, ",") But the problem is that in some function, parameters may contain a comma "," caracter.here is an exemple of javascript function:my_JS_function(12,0,false, ' my text contain a comma , !!', true,0)Please if you have an idea to catch all arguments of any javascript function ?thinks a lot Link to comment Share on other sites More sharing options...
sohfeyr Posted September 24, 2006 Share Posted September 24, 2006 my_JS_function(12,0,false, ' my text contain a comma , !!', true,0) The Regular Expressions feature of AutoIt is currently very volitile and subject to extensive change. that is why it isn't in the official documentation. You can wrap the regex capabilities of another language in a COM object (or parallel-running exe) if you like. Try using this regular expression. The information you want is in the param groupof which there may be any number of matches per arglist capture. .Net or Basic: (?<funcname>[^\(]+)(?<arglist>\((?<paramitem>(?<param>'[^']*'|[^,\)]+)(?<delim>, ?)?)*\)) java script: /(?<funcname>[^\(]+)(?<arglist>\((?<paramitem>(?<param>'[^']*'|[^,\)]+)(?<delim>, ?)?)*\))/ Perl (string), C or : "(?<funcname>[^\\(]+)(?<arglist>\\((?<paramitem>(?<param>'[^']*'|[^,\\)]+)(?<delim>, ?)?)*\\))" Perl (m// operator): m/(?<funcname>[^\(]+)(?<arglist>\((?<paramitem>(?<param>'[^']*'|[^,\)]+)(?<delim>, ?)?)*\))/ Python: r"(?<funcname>[^\(]+)(?<arglist>\((?<paramitem>(?<param>'[^']*'|[^,\)]+)(?<delim>, ?)?)*\))" DEBUG: expandcollapse popupmy_JS_function my_JS_function my_JS_function( my_JS_function(backtrack my_JS_function(12 my_JS_function(12 my_JS_function(12, my_JS_function(12, my_JS_function(12,backtrack my_JS_function(12,0 my_JS_function(12,0 my_JS_function(12,0, my_JS_function(12,0, my_JS_function(12,0,backtrack my_JS_function(12,0,false my_JS_function(12,0,false my_JS_function(12,0,false, my_JS_function(12,0,false, my_JS_function(12,0,false, my_JS_function(12,0,false, ' my_JS_function(12,0,false, ' my text contain a comma , !! my_JS_function(12,0,false, ' my text contain a comma , !!' my_JS_function(12,0,false, ' my text contain a comma , !!' my_JS_function(12,0,false, ' my text contain a comma , !!', my_JS_function(12,0,false, ' my text contain a comma , !!', my_JS_function(12,0,false, ' my text contain a comma , !!', my_JS_function(12,0,false, ' my text contain a comma , !!', backtrack my_JS_function(12,0,false, ' my text contain a comma , !!', true my_JS_function(12,0,false, ' my text contain a comma , !!', true my_JS_function(12,0,false, ' my text contain a comma , !!', true, my_JS_function(12,0,false, ' my text contain a comma , !!', true, my_JS_function(12,0,false, ' my text contain a comma , !!', true,backtrack my_JS_function(12,0,false, ' my text contain a comma , !!', true,0 my_JS_function(12,0,false, ' my text contain a comma , !!', true,0 my_JS_function(12,0,false, ' my text contain a comma , !!', true,0backtrack my_JS_function(12,0,false, ' my text contain a comma , !!', true,0backtrack my_JS_function(12,0,false, ' my text contain a comma , !!', true,0backtrack my_JS_function(12,0,false, ' my text contain a comma , !!', true,0backtrack my_JS_function(12,0,false, ' my text contain a comma , !!', true,0 my_JS_function(12,0,false, ' my text contain a comma , !!', true,0) my_JS_function(12,0,false, ' my text contain a comma , !!', true,0) Match found I love regular expressions Mine:Time Functions - Manipulate the system clock! | WinControlList (WinGetClassList++) | .Net Setup Wrapper, Detect or install .Net | Writing and using a VB .NET COM object in AutoItNot mine, but highly recommended:AutoItTreeViewExtension plugin | Menu code | Callback helper dll | Auto3Lib - Control the uncontrollable | Creating COM objects in AutoIt | Using .Net framework classes in AutoIt Link to comment Share on other sites More sharing options...
mary Posted September 24, 2006 Author Share Posted September 24, 2006 thinks sohfeyr for you help ! also i love regexp but , as you said, it have problem in autoit..., using regexp from other external tools (exe or com object) is a solution but it decrease speed of code ! specially when speed is important for the goal of project. any way i'll tray Javascript library/com but dont know how to call javascript code from autoit... Link to comment Share on other sites More sharing options...
sohfeyr Posted September 24, 2006 Share Posted September 24, 2006 (edited) using regexp from other external tools (exe or com object) is a solution but it decrease speed of code ! specially when speed is important for the goal of project. any way i'll tray Javascript library/com but dont know how to call javascript code from autoit... I've never heard of a way to call Javascript code from AutoIt either. You might be able to run an HTA file, but not with normal security measures in place. Look here for a way to call Perl functions from AutoIt. That *should* include Perl's support for regular expressions, and you are far more likely to find up-to-date documentation for Perl RegExp... Other people have had great successes with wrapping functions in FreeBasic. (See "Callback helper dll" in my signature.) I realize this isn't exactly what you were wanting, but I wouldn't want to give you a bum steer into code that uses a function under renovation. AutoIt syntax and maybe even support for RegExp is up in the air. I suppose you could use those functions as-is, but what happens when another beta comes along with a function you need? Your RegExp support is suddenly full of bugs. It is a serious maintainability problem! (See all the people who got bugs in their code when DLLStructDelete was removed? Think that but without a simple fix.) That's why I ended up wrapping the .Net RegEx, Group and Match objects and exposed them inside another process that would be running anyways. If you just want simple parsing, try this (very rough, untested, and honestly I'm not convinced that it would go any faster than signalling another program that is already running): Func ImmunizeQuotedCommas(ByRef $str, $offset=-1) $firstquote = StringIndexOf($str, "'", $offset+1) $secondquote = StringIndexOf($str, "'", $firstquote+1) $commaIdx = StringIndexOf($str, ",", $firstquote+1) If $commaIdx < $secondquote then $str=StringReplace($str, $commaIdx, "") ; = Alt-0131, Windows: Western; Alt-0192, Unicode ImmunizeQuotedCommas($str, $secondQuote) ElseIf $commaIdx > $secondquote then ImmunizeQuotedCommas($str, $commaIdx) ElseIf $commaIdx = 0 then ; No more parameters, and no commas in current string Return EndIf Return EndFunc Func StringIndexOf($str, $char, $startidx) For $i = $startidx to StringLen($str)-$startIdx If StringMid($str, $i) = $char then Return $i EndIF Next Return 0 EndFunc You can then use StringSplit freely, as long as you replace any occurrances of (or whatever symbol) with commas in the individual strings. This only supports one comma per quoted string (I wouldn't want to have to take all the fun out of this for you ) but you can easily break that conditional into parts and put the first part in a While loop with the $commaIdx = line. I still think regular expressions are the better solution, even if implementing them right now in any maintainable form adds a module to your overall software architecture. But that's just me. I'm sure a lot of people will disagree and favor the simpler (more elementary) approach of manual parsing. I wrote a program using the more elementary technique, and it is such a maintenance nightmare I'm writing version 2.0 of it in my spare time as a matter of both pride and necessity. If you foresee doing a lot of parsing, I strongly encourage you to hitch your wagon to a wrapped RegExp engine that is already established. Edit: StringInStr doesn't have a startindex parameter! Edited September 24, 2006 by sohfeyr Mine:Time Functions - Manipulate the system clock! | WinControlList (WinGetClassList++) | .Net Setup Wrapper, Detect or install .Net | Writing and using a VB .NET COM object in AutoItNot mine, but highly recommended:AutoItTreeViewExtension plugin | Menu code | Callback helper dll | Auto3Lib - Control the uncontrollable | Creating COM objects in AutoIt | Using .Net framework classes in AutoIt Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted September 24, 2006 Moderators Share Posted September 24, 2006 (edited) Edit: OOps... Not working BRB Edit2: Messy, but should work -expandcollapse popup#include <array.au3> $s = "MsgBox)" $a = _GetParams($s) If @error = 1 Then MsgBox(64, 'Info', 'Not a function') $s = "MsgBox()" $a = _GetParams($s) If @error = 2 Then MsgBox(64, 'Info', 'No Parameter') $s = "MsgBox(0, 0, 0)" $a = _GetParams($s) _ArrayDisplay($a, '') $s = "MsgBox(0, 'Title', 'Text, write something here')" $a = _GetParams($s) _ArrayDisplay($a, '') Func _GetParams($sString) Local $aSplit = StringSplit($sString, '('), $aReturn[2], $iAdd If $aSplit[0] < 2 Then Return SetError(1, 0, 0) $aSplit = StringSplit($aSplit[2], ')') $sString = $aSplit[1] If $sString = '' Then Return SetError(2, 0, 0) ; No params If Not StringInStr($sString, ',') Then $aReturn[1] = $sString Return $aReturn EndIf $aSParm = _ReturnStringParams($sString) If IsArray($aSParm) Then For $iCC = 1 To $aSParm[0] $sString = StringReplace($sString, $aSParm[$iCC], '') Next $aSplit = StringSplit($sString, ',') ReDim $aReturn[$aSplit[0] + 1] For $iCC = 1 To $aSplit[0] If StringLen(StringStripWS($aSplit[$iCC], 8)) = 0 Then $iAdd += 1 $aReturn[$iCC] = $aSParm[$iAdd] Else $aReturn[$iCC] = $aSplit[$iCC] EndIf Next Return $aReturn EndIf Return StringSplit($sString, ',') EndFunc Func _ReturnStringParams($sString) Local $sTemp, $sSQ, $sDQ, $vDelim, $sHold, $sDiff $sTemp = $sString $sTemp = StringReplace($sTemp, '""', '~~') $sTemp = StringReplace($sTemp, "''", '@@') While StringLen($sTemp) > 0 $sSQ = StringInStr($sTemp, "'") $sDQ = StringInStr($sTemp, '"') If Not $sSQ And Not $sDQ Then ExitLoop If $sDQ > 0 And ($sSQ > $sDQ Or $sSQ = 0) Then $vDelim = '"' $sTemp = StringTrimLeft($sTemp, $sDQ) $sString = StringTrimLeft($sString, $sDQ) Else $vDelim = "'" $sTemp = StringTrimLeft($sTemp, $sSQ) $sString = StringTrimLeft($sString, $sSQ) EndIf $sDiff = StringInStr($sTemp, $vDelim, 2) If $sDiff Then $sHold &= $vDelim & StringLeft($sString, $sDiff - 1) & $vDelim & Chr(01) $sTemp = StringTrimLeft($sTemp, $sDiff) $sString = StringTrimLeft($sString, $sDiff) EndIf WEnd If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), Chr(01)) Return SetError(1, 0, 0) EndFunc Edited September 24, 2006 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
mary Posted September 24, 2006 Author Share Posted September 24, 2006 thinks a lot for your help ! finally, i'll use external regexp engine (vbs or perlxx.dll). Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted September 25, 2006 Moderators Share Posted September 25, 2006 thinks a lot for your help ! finally, i'll use external regexp engine (vbs or perlxx.dll).Typical .... However this works just fine:expandcollapse popup#include <array.au3> $s = "my_JS_function(12,0,false, ' my text contain a comma , !!', true,0))" $a = _GetParams($s) _ArrayDisplay($a, '') $s = "adofijweolj afjalsdjfoawerlamsf oas falskjdfoas fl a my_JS_function(12,0,false, ' my text contain a comma , !!', true,0) adofijaldsfjowejla knfoajsd" $a = _GetParams($s, "my_JS_function") _ArrayDisplay($a, '') Func _GetParams($sString, $sFuncName = '') If $sFuncName <> '' Then $sString = StringTrimLeft($sString, StringInStr($sString, $sFuncName) - 1) EndIf Local $aSplit = StringSplit($sString, '('), $aReturn[2], $iAdd If $aSplit[0] < 2 Then Return SetError(1, 0, 0) $aSplit = StringSplit($aSplit[2], ')') $sString = $aSplit[1] If $sString = '' Then Return SetError(2, 0, 0) ; No params If Not StringInStr($sString, ',') Then $aReturn[1] = $sString Return $aReturn EndIf $aSParm = _ReturnStringParams($sString) If IsArray($aSParm) Then For $iCC = 1 To $aSParm[0] $sString = StringReplace($sString, $aSParm[$iCC], '') Next $aSplit = StringSplit($sString, ',') ReDim $aReturn[$aSplit[0] + 1] For $iCC = 1 To $aSplit[0] If StringLen(StringStripWS($aSplit[$iCC], 8)) = 0 Then $iAdd += 1 $aReturn[$iCC] = $aSParm[$iAdd] Else $aReturn[$iCC] = $aSplit[$iCC] EndIf Next Return $aReturn EndIf Return StringSplit($sString, ',') EndFunc Func _ReturnStringParams($sString) Local $sTemp, $sSQ, $sDQ, $vDelim, $sHold, $sDiff $sTemp = $sString $sTemp = StringReplace($sTemp, '""', '~~') $sTemp = StringReplace($sTemp, "''", '@@') While StringLen($sTemp) > 0 $sSQ = StringInStr($sTemp, "'") $sDQ = StringInStr($sTemp, '"') If Not $sSQ And Not $sDQ Then ExitLoop If $sDQ > 0 And ($sSQ > $sDQ Or $sSQ = 0) Then $vDelim = '"' $sTemp = StringTrimLeft($sTemp, $sDQ) $sString = StringTrimLeft($sString, $sDQ) Else $vDelim = "'" $sTemp = StringTrimLeft($sTemp, $sSQ) $sString = StringTrimLeft($sString, $sSQ) EndIf $sDiff = StringInStr($sTemp, $vDelim, 2) If $sDiff Then $sHold &= $vDelim & StringLeft($sString, $sDiff - 1) & $vDelim & Chr(01) $sTemp = StringTrimLeft($sTemp, $sDiff) $sString = StringTrimLeft($sString, $sDiff) EndIf WEnd If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), Chr(01)) Return SetError(1, 0, 0) EndFuncRun it, It will even dig through it similar to RegExp ... Or try to use the StringRegExp() internally.... I only did this because of the comment of wanting to stay native. And as about as fast as you are going to get calling outside apps to do the work. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
MHz Posted September 25, 2006 Share Posted September 25, 2006 thinks a lot for your help !finally, i'll use external regexp engine (vbs or perlxx.dll).Have a look here at using ScriptControl object to run external regex. Link to comment Share on other sites More sharing options...
mary Posted September 25, 2006 Author Share Posted September 25, 2006 (edited) SmOke_N, you code works ! thinks for your help.MHz, thinks for your StringRegExpVB.au3 (we are waiting for a StringRegExpJS.au3 )Hope a mature RegExp implementation for autoit ! Edited September 25, 2006 by mary Link to comment Share on other sites More sharing options...
MHz Posted September 25, 2006 Share Posted September 25, 2006 (edited) MHz, thinks for your StringRegExpVB.au3 (we are waiting for a StringRegExpJS.au3 ) Hope a mature RegExp implementation for autoit !$vbs.language = "vbscript" and modify the regex code to jscript. The regex syntax for regex can be found in script56.chm. Edited September 25, 2006 by MHz Link to comment Share on other sites More sharing options...
mary Posted September 26, 2006 Author Share Posted September 26, 2006 (edited) Finally i found an elegant an very rapid solution (maybe more speed than regexp, specially when there is a lot of arguments. #include <Array.au3> $texte="1,2,'this is an text argument containing a comma , and an other comma , no problem !! ',4,'othertexte'" ; juste a list of arguments Func ready_for_split($t) ; $t is a the list of arguments (the hole string beween parentheses) $t=StringSplit($t,"") Local $istxt=0 $r="" For $i=1 to $t[0] IF $t[$i]="'" Then $istxt= not $istxt EndIf IF $t[$i]="," And $istxt then $t[$i]="ß" ; this is an exotic caracter that we can replace it with the comma after split EndIf $r=$r & $t[$i] Next Return $r EndFunc $tab=StringSplit(ready_for_split($texte),",") _ArrayDisplay($tab,"splited and ready to replace 'ß' with ',' ;)") Edited September 27, 2006 by mary Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now