[英]Regex catch only the second occurence
您好,我使用此正则表达式模式:
.*@.*\:.*#\s(.*)
在此文本上:
t@ubuntu:/opt/test# cd /opt/blabla/¢ ־.P־.®Z[P§..P.#ְ״toot@bubuntu:/opt/testo# nano /etc/d× ־.P־.®Z[_§..
正则表达式只捕获
nano /etc/d× ־.P־.®Z[_§..
我试图仅捕获命令cd /opt/blabla
和nano /etc/d
为什么正则表达式不捕获cd /opt/blabla
?
编辑:我试图首先将所有非ascii字符转换为空格,现在文本看起来像:
't@ubuntu:/opt/volatility# cd /opt/Kazaar/ .P . Z[P ..P.# root@ubuntu:/opt/Kazaar# nano /etc/d .P . Z[_ ..'
每个以空格结尾的命令,因此我将正则表达式更改为:
""".*@.*\:.*#\s(.*)\s"""
但是它仍然只捕获不带cd的nano命令。
您的比赛太贪婪了,试试这个 :
/.*?@.*?\:.*?#\s(.*? .*?) /
为什么要尝试在比赛前获得最少的字符数。 假定#后面有两个“单词”,以空格隔开。
如果您的文本包含CR字符以分隔出命令会更好,因为无法在不对数据进行消毒的情况下以100%的准确度确定您要查找的命令和参数,因为无法确定“末尾”。线”。
对于此特殊用例,使用非ASCII字符,以下正则表达式将捕获完整命令:
[^#]*#\s([\x00-\x7F]*)
Ubuntu命令提示符与命令用#
符号分隔。 我们以[^#]
而不是.*
开头的原因是因为.*
太贪心:它将消耗#
所有实例(最后一个除外)。 因此,我们必须首先明确告诉正则表达式不匹配任何#
字符。
上面的正则表达式将捕获命令名称和任意数量的ASCII参数,因此您应将其用于代码的原始版本(不要用空格替换所有非ASCII字符)。 这是输出:
cd /opt/blabla/
nano /etc/d
当它们之间仅由空格分隔时,也可以使用稍微复杂一些的正则表达式来解析UNIX命令和命令提示符。 因此,在删除了非ASCII字符并修剪了所有多余的空格之后,您将获得如下所示的一行:
t@ubuntu:/opt/test# cd /opt/blabla/ toot@bubuntu:/opt/testo# nano /etc/d
然后,您可以使用先行断言来仅匹配命令及其参数:
[^\x64 ]+@[^#]+#\s*(.+?(?=\s+[^\x64 ]+@|\s*$))
最后,也是最复杂的一点,如果您有一条不一致的行,其中某些命令由空格分隔,而其他命令则由非ASCII字符分隔,则可以使用以下命令:
[^\x64 ]+@[^#]+#\s*([\x00-\x7F]+(?=[^\x00-\x7F]+|\s+[^\x64 ]+@|\s*$))
第一部分[^\\x64 ]+@[^#]+#
涵盖了Ubuntu提示符。 然后是一个任意的空格\\s*
,然后该组将尽可能多地匹配ASCII字符,而不会遇到任何非ASCII字符,行尾或其他UNIX提示符。 这意味着它也适用于带有多个参数的UNIX命令,例如mv
或cp
在python 3.5中
In [1]: import re
In [2]: string = 't@ubuntu:/opt/test# cd /opt/blabla/¢ ־.P־.®Z[P§..P.#ְ״toot@bubuntu:/opt/testo# nano /etc/d× ־.P־.®Z[_§..'
In [3]: pattern = '\w+\ (\/\w+)+'
In [4]: list(re.finditer(pattern,string))
Out[4]:
[<_sre.SRE_Match object; span=(20, 34), match='cd /opt/blabla'>,
<_sre.SRE_Match object; span=(80, 91), match='nano /etc/d'>]
您可以通过.group(0)
访问匹配项
In [5]: list(re.finditer(pattern,string))[0].group(0)
Out[5]: 'cd /opt/blabla'
In [6]: list(re.finditer(pattern,string))[1].group(0)
Out[6]: 'nano /etc/d'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.