假设我有一个特定的文件,如下所示:
#tata toto
tata titi
tata tutu titi
#tata titi
tata toto #ZZZ
tata toto #ZZZ
#tata toto #ZZZ
tata titi #YYY
#tata titi #YYY
tata titi toto
我想匹配每行:
例如,如果
tata titi => \1=tata \2=" titi" \3=null \4=null
tata titi toto => \1=tata, \2=" titi ", \3=toto, \4=null
tata toto tutu => \1=tata, \2=" ", \3=toto, \4=" tutu"
我尝试过此正则表达式:
^(tata)(.*)(toto)?(.*)
但是.*
的捕获量超出了预期。因此,toto永远不会被捕获。
你会怎么做?
为了提供更多的上下文,我想解析一个/ etc / hosts:如果我找到了一个特定的IP(这里是tata),但是此行不包含主机名别名(此处是toto),我们添加它,并保留所有主机名和已经定义的主机名别名以及注释。
谢谢, 拉乌尔
答案 0 :(得分:3)
您可以将此正则表达式与可选匹配项和否定前瞻配合使用:
^(tata)( +(?:(?!toto)\S+ *|))(toto|)(.*)$
RegEx详细信息:
^
:开始(tata)
:匹配并捕获#1组中的tata
(
:启动捕获组#2
\ +
:匹配1个以上空格(?:
:启动非捕获组
(?!toto)
:如果我们下一个位置没有toto
\S+ *
:匹配1+个非空格字符,后跟0个或多个空格|
:或什么都没有)
:结束非捕获组)
:结束捕获组#2 (toto|)
:捕获与toto
或什么都不匹配的#3组(.*)
:捕获与其余字符匹配的第4组,直到结尾$
:结束答案 1 :(得分:0)
默认情况下,星号是贪婪的,这意味着它将消耗尽可能多的能量。尝试使用.*?
to make it "lazy"。