将所有行与开始模式和一个单词相匹配

时间:2019-11-08 21:00:43

标签: regex

假设我有一个特定的文件,如下所示:

#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

我想匹配每行:

  • 从塔塔开始
  • 捕获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),我们添加它,并保留所有主机名和已经定义的主机名别名以及注释。

谢谢, 拉乌尔

2 个答案:

答案 0 :(得分:3)

您可以将此正则表达式与可选匹配项和否定前瞻配合使用:

^(tata)( +(?:(?!toto)\S+ *|))(toto|)(.*)$

RegEx Demo

RegEx详细信息:

  • ^:开始
  • (tata):匹配并捕获#1组中的tata
  • (:启动捕获组#2
    • \ +:匹配1个以上空格
    • (?::启动非捕获组
      • (?!toto):如果我们下一个位置没有toto
      • \S+ *:匹配1+个非空格字符,后跟0个或多个空格
      • |:或什么都没有
    • ):结束非捕获组
  • ):结束捕获组#2
  • (toto|):捕获与toto或什么都不匹配的#3组
  • (.*):捕获与其余字符匹配的第4组,直到结尾
  • $:结束

答案 1 :(得分:0)

默认情况下,星号是贪婪的,这意味着它将消耗尽可能多的能量。尝试使用.*? to make it "lazy"