AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[Lib] argp v3.0 Argument Options Parser (+mod for AHK_L)
Goto page 1, 2  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Fri Nov 13, 2009 11:40 pm    Post subject: [Lib] argp v3.0 Argument Options Parser (+mod for AHK_L) Reply with quote

Keywords: argument option switch parameter parse parser function lib library regex module read command string variable value name pair fast bobo download free
License: New BSD License

Look for a new version with objects: http://www.autohotkey.com/forum/viewtopic.php?p=458004#458004

Download (~23 kb)
    The archive contains the library, demo script and full documentation.

Online Documentation

Syntax

Code:
count := argp_parse( source [, maxcount, keyname1, value1, ... keyname32, value32] )

optlist := argp_getopt( source [, keylist, caseSense, value1, ... value32] )

There are two independently working functions. They have the same regular expression at the core, but the functionality and interface differs. One creates variables for each key name and the other one returns a list with names, checking against another list of possible names (either with case sense on or off and, removing dublicates). After calling one of the functions, the variables or the list must be parsed. This is left to be done by the user. For the beginner, it is recommended to use argp_getopt() and then check with InStr() if a name exists in resulting list (with surrounding spaces).

No globals are created, no special objects or frameworks are needed.

Description

Sometimes we need to work with many optional parameters. Some of the parameters may be just logical flags only (true/false). If the function have too many such parameters, the usability is endangered. To workaround that disgrace, we can make one option string to the function. From now on, this string contains all parameters. This is comparable to the commandline.

It must be parsed to find all parts. Writing such parsers could become difficult and slow down the complete process. The parsing is tried to be made with one regex call only (with some other non dramatic lines). As long as the string is keeped simple, there should be no problem. But with growing complexity, with different values of subparameters, it is a pain to make the difference.

Specification

It works with complex option strings and the formatting is quite free. Any option must begin either with "-" or "/". Every option can have values. The spaces around values are lost, unless it is enclosed between single or double quotes. The name/value separator is optional and can be ":", "=" or " " (space). Spaces around the options are also optional. You see, its not that strict. This example string:
Code:
"-A -f:'file name.ahk'/i"

would be resolved to these 3 options
Code:
A
f
i

The option "f" would hold the value without quotes
Code:
file name.ahk

This nice example visualizes how the argp-functions sees the complex string. The green-parts are the parameter names. The orange-parts are the corresponding optional values of the parameters. Any grey-part is badly formatted and ignored, according the rules of the internally used regular expression. The red-parts are punctuation characters for separating the value from its name and marking the end of value.

This string:
Code:
-A='3/3'-/ c8-x'2 '-i--test.num: '44' /yy0 -f /f: c:"\tes"t-d\\E4 d\E\d -k:0/-t /file:'c:\t /e:1 st \file.ahk'  -e 2 /i -extra:'test/e:3 //e:4 /' /time:5:10 -date:11.08.2009

... would be seen as:
Code:
-A='3/3'-/ c8-x'2 '-i--test.num: '44' /yy0 -f /f: c:"\tes"t-d\\E4 d\E\d -k:0/-t /file:'c:\t /e:1 st \file.ahk'  -e 2 /i -extra:'test/e:3 //e:4 /' /time:5:10 -date:11.08.2009

"A", "x", "i", "test.num", "yy0", "f", "f", "d", "k", "t", "file", "e", "i", "extra", "time" and "date".
  1. An argument must start with "-" or "/".
  2. Then argument name consisting of these characters follows: a-z, A-Z, 0-9, _, ., ?, ! or @
  3. The value/name separator ":" "=" after the name is optional. A space can be used also for this.
  4. After the separator, the argument can have a value.
  5. The value can be enclosed between single or double quotes (then a separator ":" or "=" is needed).
  6. If the value is not enclosed between quotes, the next space or argument ends the value.
  7. Any space around the value is lost.

Some usage examples

The options variable holds the string given by the end user:
Code:
options := "-a:'foo -bar ' -B -c hello world"

  1. Get the count of found options. Restrict to a maximum of 8 items.
    Code:
    count := argp_parse(options, 8)

  2. Get a maximum of 3 options. Save the resulting names in variables 'name1' to 'name3' and corresponding values in 'value1' to 'value3'.
    Code:
    argp_parse(options, 3, name1, value1, name2, value2, name3, value3)

  3. Check if the options namely a", "b" and "c" exist and get a list with existing option names (with case sense on).
    Code:
    optlist := argp_getopt(options, "a b c")

The documentation contains usage examples and detailed descriptions of all functions.

Full usage example of argp_getopt() function

Code:
display(options)
{
    ; Default values of options.
    sentence = hello world

    ; Parsing options.
    optlist := argp_getopt(options, "sentence caseMod html", false, sentence_value, caseMod_value)

    Loop, Parse, optlist, %A_Space%, %A_Space%
    {
        If ("sentence" = A_LoopField)
            sentence := sentence_value
        Else If ("caseMod" = A_LoopField)
        {
            If (caseMod_value = 1)
                StringUpper, sentence, sentence, T
            Else If (caseMod_value = 2)
                StringUpper, sentence, sentence
            Else If (caseMod_value = 3)
                StringLower, sentence, sentence
        }
        Else If ("html" = A_LoopField)
            Transform, sentence, HTML, %sentence%
    }

    MsgBox %sentence%
}

Lets see how a call could look now
Code:
display("-caseMod 2 -html")

Last changes

License changed to New BSD without changing scriptrevision.
  • breaks compatibility with last version
  • general rework at internal used regular expression
  • changed: renamed library and all functions from "args" to "argp" prefix and now args() is argp_parse() and args_names() is argp_getopt()
  • changed: the special optimization with 24 elements of argp_parse() is not longer present anymore, but added optimization maxcount "8" at argp_parse()
  • changed: the resulting (return value) list of argp_getopt() reflects the sorting order from original args source, and not from specified given list
  • new: first option of argp_getopt() (argp_parse() does not support this) can be a value without key, but it is not included in count and result is saved in ErrorLevel
  • extended: key names can contain one of these characters now a-z, A-Z, 0-9, _, ., ?, ! and @

Alternative libraries

You may also want to check Yook's Parameters and switches parser
or majkinetor's Parse
or ahklerner's options.ahkl - an options object for AutoHotkey_L libraries.


Last edited by Tuncay on Mon Jul 11, 2011 12:04 pm; edited 23 times in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Fri Nov 20, 2009 11:28 pm    Post subject: Update Reply with quote

Version 1.0

Last changes
  • Added: New parameter "caseSensitive" to enable the case insensitive option.
  • Improved: It should work better, with less possible bugs.
  • Change: Renamed the library from "param" to "args". Functions renamed to "args()" and "args_p()".
  • Bug: Spaces inside values are now catched properly.
  • Bug: The character sequence "\E" should not make any problems anymore.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Sat Nov 21, 2009 11:28 am    Post subject: Reply with quote

Very much needed. Thanks.

I suggest you to use UTest for testing in this case, for both regression bugs and user satisfaction.
_________________
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Sat Nov 21, 2009 10:09 pm    Post subject: Update Reply with quote

Version 0.3

Last changes
  • Improved: More robust with values of parameters.
  • Change: Status and revision of library downgraded back to Beta.

First post updated completly. Downgraded back to Beta state, because it is not that stable as I thought.

majkinetor, a quick look at your UTest library looks promising. Something like that is what I need, but I was not able to work with it. I am not really understanding it. Can you show me an example how to work with it? I mean, an real world example, not just the template found in documentation.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Sun Nov 22, 2009 8:22 pm    Post subject: Reply with quote

Sure. Ill add unit test for your option parser. Few samples, then you can extend it yourself.

Cheers.
_________________
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Sun Nov 22, 2009 9:07 pm    Post subject: Reply with quote

Args with unittest and single doc file

Notes.

1. To create documentation as single file, you run "mkdoc s"
2. Just execute _Test.ahk in UTest folder. There is only 1 simple test from which you can understand how testing work. If you are still confused I suggest you search some Unit Testing tutorial. You will ideally have every important thing in some test function and when you change the code, you run tests again and make sure non of them failes (big FAIL or OK on the bottom is overall indicator).
3. Perhaps you should provide an option to get several parameters instead of just one. I usualy do that via "Query" parameter, pQ that contains list of things I want to extract. I am also concerned about many RegEx calls you will get when you get ALL of your parameters.
4. You will need to fix your "Known BUG or LIMITATION". This makes system not generally usable, as even file paths can contain - char.


BTW, if you didn't see, it, I made Parse function. The purpose is not the same, but its similar. Parse does its job in AHK manner, while your function does its jub in the cmd.exe manner.
Parse also contains UTests so you can see detailed example there.
_________________
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Sun Nov 22, 2009 9:39 pm    Post subject: Reply with quote

  1. I am working with Natural Docs. What do you mean by >>run "mkdoc s" << ? I am creating all documentation with MakeDoc.bat:
    Code:
    @echo off
    echo.
    echo Creating documentation....
    echo.

    ::path to the natural doc folder
    SET NDPATH=C:\Programme\NaturalDocs

    ::project root path
    SET ROOT=%CD%

    ::documentation folder
    SET DOC=doc



    mkdir "%ROOT%\%DOC%\_ndProj" 2>nul
    pushd "%NDPATH%"
    call NaturalDocs -i "%ROOT%" -o HTML "%ROOT%\%DOC%" -p "%ROOT%\%DOC%\_ndProj"

    popd

    ::create link to the index.html in root
    ::nircmdc shortcut "%ROOT%\%DOC%\index.html" "%ROOT%" Manual


  2. No, I am not confused. Now I understand the concept better. I had played with the function and was near to use it correctly.
  3. This project started for privately own usage, for a very simple object. The main purpose was just to check if an option exist, not to extract additional arguments or values. But it growed and the purpose seems to change a bit. Now, I am at the limit of my knowledge. I don`t like the fact to call it several times also. But before all that, the bug have to be fixed.
  4. Yes, we are of the same opinion about the BUG.


I have seen your Parse function already and added a link into the documentation.

majkinetor, thx for all what you have done here. Later, if I have more time, then I`ll have to add the Unit-Tests.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Mon Nov 23, 2009 11:58 am    Post subject: Reply with quote

Quote:
What do you mean by >>run "mkdoc s" <<

Info is here: NDoc custom installer

Quote:
Now, I am at the limit of my knowledge.

Thats the best way to improve it.

Cheers.
_________________
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Sun Nov 29, 2009 10:53 pm    Post subject: Update Reply with quote

Version 2.0

Last changes
  • Completly rewritten.

The source is completly rewritten with a complete another regular expression and core. The aim is also changed and the way its work is not the same. Before this update, every option had to be checked with every call. Now, with one function call, all up to 24 options with its value can be retrieved. There are two similair functions now.

The old known BUG is not present anymore! It seems as if everything works as it should. There is no official test code, but I have tested the functions a bit and have not found any bug yet. Test code will follow.

The first post and documentation showing and explaining all in detail. Please give feedback, if someone uses this or want to use.
_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Wed Dec 02, 2009 11:28 am    Post subject: Update Reply with quote

Version 2.1

Last changes
  • There was a bug at args_names(), which prevented to save the right value of an option with value. Not sure if this works now.
  • Spaces around the return value are not deleted anymore, for use to check with InStr(options, " A ")

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Wed Dec 02, 2009 8:44 pm    Post subject: Update Reply with quote

from 2.1 to 2.1.1 ... small update, now it works.
_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Sat Dec 05, 2009 3:52 pm    Post subject: Reply with quote

If someone tries this, please report. I would like to know if this someone needs or uses.

Note: Currently the functions uses "Critical" command of AutoHotkey. This does affect the whole thread at call place. It is planned to remove this or make use of following methode: Old_IsCritical := A_IsCritical followed later by Critical %Old_IsCritical%
_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Mon Dec 14, 2009 10:47 pm    Post subject: Update Reply with quote

Version 2.2

Last changes
  • The internal used Critical command is disabled now. This is, because it would change it for the whole thread
  • At the args() function, now VarSetCapacity() is used if not optimized option number (16, 24, 32) is specified.
  • The maximum possible number of options is changed from 24 to 32.


Usage Example of args_names()

Code:
; After call of args_names(): names contains a space separated list of case sensitive words or letters,
; with one space at beginning and end of string. Any in second parameter of args_names() defined options
; are checked for existence.  (3 possible options, 2 of them can have additional arguments)
names := args_names(_options                 ; String with the options.
    , "H m i"                                ; Options to search for.
    , true                                   ; Makes case sensitive.
    , opt_withFileNameMode, opt_maxCount)    ; Option arguments.
; Every option is checked with caseSens on and space around for existence in names.

opt_withFileName := (InStr(names, " H ", true) ? true : false)
; Use default value, if not specified with argument at "H".
If (opt_withFileNameMode = "")
{
    opt_withFileNameMode := 1
}

opt_useMaxCount := (InStr(names, " m ", true) ? true : false)
; Use default value, if not specified with argument at "m".
If (opt_maxCount = "")
{
    opt_maxCount := 1
}

; Default is case sensitive search.
opt_caseSensitive := (InStr(names, " i ", true) ? false : true) ; false : true


Later in code, you can easily check if a option was specified with
Code:
If (opt_useMaxCount = true)
{
    Loop, %opt_maxCount%
        ... { do something stupid }
}

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Sat Jan 30, 2010 10:50 pm    Post subject: Update Reply with quote

Version 3.0

Last changes
  • breaks compatibility with last version
  • general rework at internal used regular expression
  • changed: renamed library and all functions from "args" to "argp" prefix and now args() is argp_parse() and args_names() is argp_getopt()
  • changed: the special optimization with 24 elements of argp_parse() is not longer present anymore, but added optimization maxcount "8" at argp_parse()
  • changed: the resulting (return value) list of argp_getopt() reflects the sorting order from original args source, and not from specified given list
  • new: first option of argp_getopt() (argp_parse() does not support this) can be a value without key, but it is not included in count and result is saved in ErrorLevel
  • extended: key names can contain one of these characters now a-z, A-Z, 0-9, _, ., ?, ! and @

Major update! I would say it is stable now. Also the license is changed to GNU Lesser General Public License, which allows everyone using this module. Your own scripts do not need to be open source and can have any license.

Edit: License is now under the New BSD License.
_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 1886
Location: Germany

PostPosted: Sun Jul 10, 2011 8:24 pm    Post subject: Reply with quote

AHK_L
Just in case someone is interested in it. I have modified one of the functions argp_getopt() to get an associative array object and simplefied by removing all optional parameters and eliminating the additional Loops. This function is all you need and the most simple one to work with, as it works with objects. Very powerful imo. No need to include the original argp.ahk library.

Usage example:
Code:
args := "-input notes.txt"
options := getopt(args)
msgbox % options.input ; shows notes.txt


Function (based on argp_getopt):
Code:
/*
Copyright 2010,2011 Tuncay. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice, this list of
      conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above copyright notice, this list
      of conditions and the following disclaimer in the documentation and/or other materials
      provided with the distribution.

THIS SOFTWARE IS PROVIDED BY Tuncay ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Tuncay OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Tuncay.
*/
getopt(ByRef _args)
{
    _n1:="",_n2:="",_n3:="",_n4:="",_n5:="",_n6:="",_n7:="",_n8:="",_n9:="",_n10:="",_n11:="",_n12:="",_n13:="",_n14:="",_n15:="",_n6:="",_n17:="",_n18:="",_n19:="",_n20:="",_n21:="",_n22:="",_n23:="",_n24:="",_n25:="",_n26:="",_n27:="",_n28:="",_n29:="",_n30:="",_n31:="",_n32:=""
_v1:="",_v2:="",_v3:="",_v4:="",_v5:="",_v6:="",_v7:="",_v8:="",_v9:="",_v10:="",_v11:="",_v12:="",_v13:="",_v14:="",_v15:="",_v16:="",_v17:="",_v18:="",_v19:="",_v20:="",_v21:="",_v22:="",_v23:="",_v24:="",_v25:="",_v26:="",_v27:="",_v28:="",_v29:="",_v30:="",_v31:="",_v32:=""
RegExMatch(_args,"JSs`a)(?:(?:.*?\s*)[-/](?P<n1>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v1>.+?)')(?=.*?)|""(?:(?P<v1>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v1>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n2>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v2>.+?)')(?=.*?)|""(?:(?P<v2>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v2>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n3>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v3>.+?)')(?=.*?)|""(?:(?P<v3>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v3>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n4>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v4>.+?)')(?=.*?)|""(?:(?P<v4>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v4>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n5>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v5>.+?)')(?=.*?)|""(?:(?P<v5>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v5>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n6>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v6>.+?)')(?=.*?)|""(?:(?P<v6>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v6>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n7>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v7>.+?)')(?=.*?)|""(?:(?P<v7>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v7>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n8>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v8>.+?)')(?=.*?)|""(?:(?P<v8>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v8>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n9>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v9>.+?)')(?=.*?)|""(?:(?P<v9>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v9>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n10>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v10>.+?)')(?=.*?)|""(?:(?P<v10>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v10>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n11>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v11>.+?)')(?=.*?)|""(?:(?P<v11>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v11>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n12>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v12>.+?)')(?=.*?)|""(?:(?P<v12>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v12>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n13>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v13>.+?)')(?=.*?)|""(?:(?P<v13>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v13>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n14>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v14>.+?)')(?=.*?)|""(?:(?P<v14>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v14>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n15>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v15>.+?)')(?=.*?)|""(?:(?P<v15>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v15>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n16>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v16>.+?)')(?=.*?)|""(?:(?P<v16>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v16>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n17>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v17>.+?)')(?=.*?)|""(?:(?P<v17>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v17>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n18>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v18>.+?)')(?=.*?)|""(?:(?P<v18>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v18>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n19>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v19>.+?)')(?=.*?)|""(?:(?P<v19>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v19>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n20>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v20>.+?)')(?=.*?)|""(?:(?P<v20>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v20>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n21>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v21>.+?)')(?=.*?)|""(?:(?P<v21>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v21>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n22>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v22>.+?)')(?=.*?)|""(?:(?P<v22>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v22>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n23>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v23>.+?)')(?=.*?)|""(?:(?P<v23>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v23>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v24>.+?)')(?=.*?)|""(?:(?P<v24>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v24>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v25>.+?)')(?=.*?)|""(?:(?P<v25>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v25>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v26>.+?)')(?=.*?)|""(?:(?P<v26>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v26>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v27>.+?)')(?=.*?)|""(?:(?P<v27>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v27>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v28>.+?)')(?=.*?)|""(?:(?P<v28>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v28>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v29>.+?)')(?=.*?)|""(?:(?P<v29>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v29>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v30>.+?)')(?=.*?)|""(?:(?P<v30>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v30>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v31>.+?)')(?=.*?)|""(?:(?P<v31>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v31>[^-/\s]*)\s*))?(?:(?:.*?\s*)[-/](?P<n24>[a-zA-Z0-9_?!@.]+)(?:[:=]\s*)?(\s*'(?:(?P<v32>.+?)')(?=.*?)|""(?:(?P<v32>.+?)"")(?=.*?)|[\s'""]?\s*(?P<v32>[^-/\s]*)\s*))?",_) ; 32 elements.
    options:=Object(),count:=0
    Loop,32 ; 32 corresponding to the maximum possible number of matching elements.
    {
        If (_n%A_Index%!="")
        {
            count:=A_Index
            options[_n%A_Index%] := _v%A_Index%
        }
    }
    ErrorLevel:=count ; Number of matching elements.
    Return options
}

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group