Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 正则表达式以任意顺序捕获命名组_Python_Regex - Fatal编程技术网

Python 正则表达式以任意顺序捕获命名组

Python 正则表达式以任意顺序捕获命名组,python,regex,Python,Regex,我有一个场景,需要使用对Python的re.sub()的一个调用来查找和替换字符串中的项。如果这种限制听起来像是做作的,那就把它看成是一种心理练习,但要知道这是我必须要面对的现实约束。 我想匹配并替换以下任一行: foo -some-arg -o %output %input foo %input -other-random-arg=baz -o %output 为此: bar %output %input.out 文件名%input和%output可以是与[a-zA-Z0-9.-]+匹配的

我有一个场景,需要使用对Python的re.sub()的一个调用来查找和替换字符串中的项。如果这种限制听起来像是做作的,那就把它看成是一种心理练习,但要知道这是我必须要面对的现实约束。

我想匹配并替换以下任一行:

foo -some-arg -o %output %input
foo %input -other-random-arg=baz -o %output
为此:

bar %output %input.out
文件名%input和%output可以是与
[a-zA-Z0-9.-]+
匹配的任何内容,但前面总是有
%

我想出了这个替代品,但不太管用

    r'''(?x)                     # Begin verbose regex
        foo[ ]                   # foo and a space
        (?=.*?-o[ ]                  # Lookahead for the first occurrence of -o
            (?P<a>%\S+\b)                # Output filename -> Group 'a'
        )
        (?=.*?                       # Lookahead from the same place as the first lookahead
                                     # so the two filenames can match in any order.
            (?!-o[ ]%\S+\b)              # Do not match the output file
            (?P<b>%\S+\b)                # Any filename -> Group 'b'
        ).*                      # Match anything ''',
    r'bar \g<b> \g<a>.out'       # Replacement

有没有一种方法可以捕获这两个文件名的显示顺序?似乎如果我能在匹配一个lookahead时推进正则表达式引擎的指针,我就能做到这一点。

因为所有参数都以破折号开头,而且输入和输出总是出现一次,所以可以使用这种忽略顺序的模式:

foo(?: -o (?P<output>\S+)| -\S+| (?P<input>\S+))+

注意:如果您想处理包含空格(在命令行中转义)的文件名,您需要将
\S+
更改为
(?:[^\S\\]+(?:\\.[^\S\\\]*)*(?:\.[^\S\\]*)
(仅用于输入和输出)

,这太棒了,谢谢!现在甚至不需要组命名(尽管可能从来都不需要)。
foo(?: -o (?P<output>\S+)| -\S+| (?P<input>\S+))+
bar \1 \2.out