从字符串| regex | php解析参数

从字符串| regex | php解析参数,php,regex,iptables,Php,Regex,Iptables,解析字符串中的参数时遇到问题 参数定义如下: 可以用短符号或长符号书写,例如: -a/--long 字符范围从[a-z0-9]短到[a-z0-9\-]长,例如: ——带破折号的长型 可以有一个值,但不必有,例如: -测试/--aaaa 可以有多个参数,不带引号,p.ex: -a val1 val2 (应作为一个组捕获:value=“val1 val2”) 可以在引号中包含自定义文本 --custom“这里可以承受一切,-test:(“ 参数前面可以有一个“!” !--测试测试/!-a 值的内部

解析字符串中的参数时遇到问题

参数定义如下:

  • 可以用短符号或长符号书写,例如: -a/--long

  • 字符范围从[a-z0-9]短到[a-z0-9\-]长,例如: ——带破折号的长型

  • 可以有一个值,但不必有,例如: -测试/--aaaa

  • 可以有多个参数,不带引号,p.ex: -a val1 val2 (应作为一个组捕获:value=“val1 val2”)

  • 可以在引号中包含自定义文本 --custom“这里可以承受一切,-test:(“

  • 参数前面可以有一个“!” !--测试测试/!-a

  • 值的内部可以有“-” -带破折号的值

所有这些参数都包含在一个长字符串中,例如:

-a val1!-b val2--other“string with crazy-a--test stuff inside”-param with dash val1 val2--test value with dash!-c-d!-test

--编辑----

还有
--带破折号的参数值

--结束编辑---

这是我能得到的最接近的结果:

/(?:(?p\!)?(?p\-{1,2}\S+)($)(?p.+(?=(?:[\!\124;\)))/U

不幸的是,当涉及到引号内的自由文本值时,以及当一个没有值的参数后跟下一个参数时,它会中断

(我尝试解析iptables save的输出,以防您感兴趣。此外,我以前可能可以用另一种奇特的方式拆分字符串,以避免使用hugh regex,但我看不到它)

非常感谢你的帮助

--最终解决方案--

对于PHP>=5.6

(?!)?\s*(?-?\w[\w-]*)\s*(?:\s*(?:\w\s*)[“]”](?:[^“\\]*(?:\.[^”\]*)[“]”])*)\K

演示:

对于PHP<5.6

(?\!)?\s*(?RegEx:

正则表达式:


哇,太好了。非常感谢。还有一件事-这是我的错误,因为我刚才在文本中提到了,但在示例中没有提到。正则表达式还需要将a值与破折号匹配:“-b值与破折号”,然后请将
\w+
更改为
[^'\s]+
。不幸的是,这不起作用。如果我能想出一个解决方案,我会试试的。无论如何,谢谢;)这只是记录在案,现在对我有效:
(?!)?\s*(?-?\w[\w-]*)\s*(?:\s*(?:[\w][\w\-]*.[“]”(?:[^'\\\]*(?:\^'\\\\\\\\\].*)[”)*(?:\\^'\\\\\\\\\\].*)[“))*)\K
“\S+到\S*,否则它不会再识别像-ab这样的东西。呵呵,似乎永远不会结束的故事:)。再次感谢你的更新。哇,太棒了。非常感谢你。还有一件事——这是我的错误,因为我只是在文中提到了,但没有在示例中提到。正则表达式还需要将a值与破折号进行匹配:“-b值与破折号”然后请将
\w+
更改为
[^'\s]+
。不幸的是,这不起作用。如果我找到了解决方案,我会尝试一下。无论如何,谢谢;)只是为了记录在案,这现在对我有效:
(?!)\s*(?\w[\w-]*)\s*(?:\s*(?:\s*(?:[\s*(?:::[\w][\w\]*]*.[\124](?::*):“\ \ \”。[^“\\]*)*)['“])*)\K
感谢您将“新”\S+更改为\S*,否则它将无法识别类似-ab的内容。呵呵,似乎是永无止境的故事:)。再次感谢您的更新。
(?<inverted>!)?\s*(?<name>--?\w[\w-]*)\s*(?<values>(?:\s*(?:\w\S+|["'](?:[^"'\\]*(?:\\.[^"'\\]*)*)['"]))*)\K
 (?<inverted> ! )?             # (1) Named-capturing group for inverted result
 \s*                           # Match any spaces
 (?<name> --? \w [\w-]* )      # (2) Named-capturing group for parameter name
 \s*                           # Match any spaces
 (?<values>                    # (3 start) Named capturing group for values
      (?:                           # Beginning of a non-capturing group (a)
           \s*                      # Match any spaces
           (?:                      # Beginning of a non-capturing group (b)
                \w\S+                   # Match a [a-zA-Z0-9_] character then any non-whitespace characters
             |                          # Or
                ["']                    # Match a qoutation mark
                (?:                     # Beginning of a non-capturing group (c)
                     [^"'\\]*               # Match anything except `"`, `'` or `\`
                     (?: \\ . [^"'\\]* )*   # Match an escaped character then anyhthing except `"`, `'` or `\` as much as possible
                )                       # End of non-capturing group (c)
                ['"]                    # Match qutation pair
           )                        # End of non-capturing group (b)
      )*                            # Greedy (a), end of non-capturing group (a)
 )                             # (3 end)
 \K                            # Reset allocated memory of all previously matched characters
<?php 
    
$str = '-a val1 ! -b val2 --custom "string :)(#with crazy -a --test stuff inside" --param-with-dash val1 val2 -c ! -d ! --test';
$re = <<< 'RE'
~(?<inverted>!)?\s*(?<name>--?\w[\w-]*)\s*(?<values>(?:\s*(?:\w\S+|["'](?:[^"'\\]*(?:\\.[^"'\\]*)*)['"]))*)\K~
RE;

preg_match_all($re, $str, $matches, PREG_SET_ORDER);
print_r(array_map('array_filter', $matches));
Array
(
    [0] => Array
        (
            [name] => -a
            [2] => -a
            [values] => val1
            [3] => val1
        )

    [1] => Array
        (
            [inverted] => !
            [1] => !
            [name] => -b
            [2] => -b
            [values] => val2
            [3] => val2
        )

    [2] => Array
        (
            [name] => --custom
            [2] => --custom
            [values] => "string :)(#with crazy -a --test stuff inside"
            [3] => "string :)(#with crazy -a --test stuff inside"
        )

    [3] => Array
        (
            [name] => --param-with-dash
            [2] => --param-with-dash
            [values] => val1 val2
            [3] => val1 val2
        )

    [4] => Array
        (
            [name] => -c
            [2] => -c
        )

    [5] => Array
        (
            [inverted] => !
            [1] => !
            [name] => -d
            [2] => -d
        )

    [6] => Array
        (
            [inverted] => !
            [1] => !
            [name] => --test
            [2] => --test
        )

)