Jump to content

StringRegExp(): optional capture


Recommended Posts

This regexp

'(?xU) (?!Func)  (Local)? \  (\$\w+) \s* (\=) \s* (\w+) \( ([^\(]*) \)'

matches

Local $gNowSecs = NowSecs($a,45)

with flag=3, and StringRegExp returns an array: [ "Local","$gNowSecs","=","NowSecs","$a,45"]

but it does not match

$gNowSecs = NowSecs($a,45)

How can I get StringRegExp() to handle both strings? In the latter case, I would prefer that it return ["$gNowSecs","=","NowSecs","$a,45"]

BTW I think the help for StringRegExp() is excellent. I have consulted  pcrepattern man page .

Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Link to comment
Share on other sites

The number of capturing groups in the pattern dictates how many results you're going to get. That means that you can't expect this to work without giving you an empty capture first when Local isn't there. Also the whitespace following optional Local is not itself optional and this is why your pattern fails.

Local $s = "$gNowSecs = NowSecs($a,45)"
Local $a = StringRegExp($s, '(?xU) (?!Func)  (Local\ )? (\$\w+) \s* (\=) \s* (\w+) \( ([^\(]*) \)', 3)
_ArrayDisplay($a)

Observe that the first capture is now an empty string.

Thank you for compliments!

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Thank you for solving my problem.

And I have found that this works for Local, Global and none:

(?xU) (?!Func)  ((?|Local|Global))? \s* (\$\w+) \s* (\=) \s* (\w+) \( ([^\(]*) \)

I find it interesting that the the match made by an alternative group, which is always non-capturing , can be captured by using plain ( ... )

Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Link to comment
Share on other sites

Of course. Think of groups (capturing or not) as block constructs of a programming language (which PCRE is).

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I am now trying to get my regexp to handle PopulateLvlFnamAr('nat',$gNatLvlFnamAr)

The proposed regexp is

(?xU) (?!Func)  ((?|Local|Global))? \s* (((\$\w+) \s*)? (?:\=))? \s* (\w+) \( ([^\(]*) \)

For PopulateLvlFnamAr('nat',$gNatLvlFnamAr) it produces

["","","","","PopulateLvlFnamAr","'nat',$gNatLvlFnamAr"]

and for Local $gNowSecs = NowSecs(12,34) it produces

["Local","$gNowSecs =","$gNowSecs ","$gNowSecs","NowSecs","12,34"]

Ideally, I would like the elements of the vector to be [ Local/Global, var, function, arguments] where Local/Global, var and arguments can be empty.

What am I not understanding?

How fo I get from where I am now to where I want to go?

Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Link to comment
Share on other sites

May I suggest

#Include <Array.au3>

$str1 = "  Local $gNowSecs = NowSecs(12,34)"
$res1 = StringRegExp($str1, '(?x) \s*((?|Local|Global))? \s* (\$\w+)? \s*=?\s* (\w+) \(? ([^\)]*) ', 3)

$str2 = " PopulateLvlFnamAr('nat',$gNatLvlFnamAr)"
$res2 = StringRegExp($str2, '(?x) \s*((?|Local|Global))? \s* (\$\w+)? \s*=?\s* (\w+) \(? ([^\)]*) ', 3)

 _ArrayDisplay($res1)
 _ArrayDisplay($res2)

 

Edited by mikell
Link to comment
Share on other sites

For parsing AutoIt code in general you'll need a grammar parser. Not as simple as it looks first, but you can still start with regexps. I played a bit with this but never took the time/pain to finish it:

Local $REdef_Spacing =              '(?(DEFINE) (?<spacing> (?: \ \t )* ) )'

Local $REdef_Directive =            '(?(DEFINE) (?<directive> ^ (?&spacing) # .* ) )'

Local $REdef_Blkcomment =           '(?(DEFINE) (?m) (?<blkcomment> (?: ^ (?&spacing) #c (?: s | omments-start ) .*? ^ (?&spacing) #c (?: e | omments-end ) .*? \R (?-m) ) )'
Local $REdef_Linecomment =          '(?(DEFINE) (?<linecomment> (?&spacing) ; .*? $ ) )'

Local $REdef_String =               '(?(DEFINE) (?<string> (?: " [^"]*? " | '' [^'']*? '' )+ ) )'
Local $REdef_Integer =              '(?(DEFINE) (?<integer> [-+]? \d+ ) )'
Local $REdef_Real =                 '(?(DEFINE) (?<real> [-+]? \d* \. \d+ (?: E [-+]? \d*) ) )'
Local $REdef_Boolean =              '(?(DEFINE) (?<boolean> \b (?: True | False ) \b ) )'
Local $REdef_Hexvalue =             '(?(DEFINE) (?<hexvalue> 0x [[:xdigit:]]+ ) )'
Local $REdef_Macro =                '(?(DEFINE) (?<macro> @ \w+ ) )'
Local $REdef_Keyword =              '(?(DEFINE) (?<keyword> \b (?: Null | Default ) \b ) )'
Local $REdef_Fctname =              '(?(DEFINE) (?<fctname> \b \w+ \b ) )'
Local $REdef_Literal =              '(?(DEFINE) (?<literal> (?&spacing) (?: (?&string) | (?&hexvalue) | (?&real) | (?&integer) | (?&macro) | (?&boolean) | (?&keyword) | (?&fctname) ) (?&spacing) ) )'

Local $REdef_Varname =              '(?(DEFINE) (?<varname> \$ \w+ ) )'
Local $REdef_Operator =             '(?(DEFINE) (?<operator> (?&spacing) (?: \bAND\b | \bNOT\b | \bOR\b | <= | < | == | = | >= | > | & | + | - | \* | / | \^ ) (?&spacing) ) )'
Local $REdef_Expression =           '(?(DEFINE) (?<expression>  ) )'
Local $REdef_Rvalue =               '(?(DEFINE) (?<rvalue> (?&expression) (?: (?&operator) (?&expression) )* ) )'
Local $REdef_AssignOper =           '(?(DEFINE) (?<assignoper> += | -= | *= | /= |&= | = ) )'
Local $REdef_Lvalue =               '(?(DEFINE) (?<lvalue> (?&spacing) (?&varname) (?: (?&spacing) (?: \[ (?&rvalue) \] | \. [^\ \t\-+\*/\^\[\$.\s<=>&]+ ) )* (?&spacing) ) )'
Local $REdef_Ternary =              '(?(DEFINE) (?<ternary> (?&rvalue) \? (?&rvalue) : (?&rvalue) ) )'
...

This definitely incomplete and most probably wrong in many places. Still much work towards a pattern for "AutoIt statement". At least this gives you the idea, but a dedicated grammar parser would be more adequate.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

mikell,

The problem that I have with your pattern is that when I apply it to lines of a script, lines that do not contain calls to functions also match it.

jchd,

Thank you for your thoughts. My objective is to create a tracing utility that offers more than the existing one: one that will report values passed in parameters to calls to user-written functions. I have got a bit further. This is where I am now:

Local $regexp = '(?xJ) (?!Func)                                     '& _
    '(?|                                                            '& _
        '(Local) \s+ (\$\w+) \s+ = \s+ (\w+)                    |   '& _
        '(Global) \s+ (\$\w+) \s+ = \s+ (\w+)                   |   '& _
        '(If)  \s+ (\w+)                                        |   '& _
        '(ElseIf)  \s+ (\w+)                                    |   '& _
        '(Until)  \s* (?!\() \s* (?!\() \s* (?!Not) \s+ (\w+)   |   '& _
        '(While)  \s+ (\w+)                                     |   '& _
        '\s* (\$\w*) \s+ = \s+ (\w+)                            |   '& _
        ' (\w+)                                                     '& _
    ')                                                              '& _
    '\(                                                             '& _
    '([^\)]*)                                                       '& _
    '\)                                                             '

But I think that you are correct: even for my subset of the language, I need to write a grammar parser. The start that you have made will be a help.

Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Link to comment
Share on other sites

I'm not so sure it could help you: it may reveal more of a pitfall than anything.

I was testing nesting (?(DEFINE) ...) behavior with PCRE and had the idea to write this. So you understand it isn't any close to something well tought out. Also you know the slightiest mistake with regexp can put the whole thing down, so look at it like warm nitroglycerin.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...