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
Regex 正则表达式能否返回找到匹配项的行的编号?_Regex_Replace_Find_Editor - Fatal编程技术网

Regex 正则表达式能否返回找到匹配项的行的编号?

Regex 正则表达式能否返回找到匹配项的行的编号?,regex,replace,find,editor,Regex,Replace,Find,Editor,在文本编辑器中,我想用找到该单词的行号的编号替换给定的单词。这在正则表达式中是可能的吗?我不知道有哪种编辑器能做到这一点,除了扩展允许任意扩展的编辑器之外 不过,您可以轻松地使用perl来完成这项任务 perl -i.bak -e"s/word/$./eg" file 或者如果要使用通配符 perl -MFile::DosGlob=glob -i.bak -e"BEGIN { @ARGV = map glob($_), @ARGV } s/word/$./eg" *.txt 递归、自引用组(

在文本编辑器中,我想用找到该单词的行号的编号替换给定的单词。这在正则表达式中是可能的吗?

我不知道有哪种编辑器能做到这一点,除了扩展允许任意扩展的编辑器之外

不过,您可以轻松地使用
perl
来完成这项任务

perl -i.bak -e"s/word/$./eg" file
或者如果要使用通配符

perl -MFile::DosGlob=glob -i.bak -e"BEGIN { @ARGV = map glob($_), @ARGV } s/word/$./eg" *.txt
递归、自引用组(Qtax技巧)、反向Qtax或平衡组 导言

在输入的底部添加一个整数列表的想法类似于著名的数据库黑客(与regex无关),其中一个连接到一个整数表。我最初的回答使用了@Qtax技巧。当前答案使用递归、Qtax技巧(直接或反向变化)或平衡组

是的,有可能。。。有一些警告和正则表达式欺骗。

(?sm)(?=.*?pig)(?:(?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*+.*?\Kpig(?=[^:]+(?(1)\1):(\d+))
\2
my cat
dog
my 3
my cow
my mouse

:1:2:3:4:5:6:7
(?m)(?<=\A(?<c>^(?:(?!pig)[^\r\n])*(?:\r?\n))*.*?)pig(?=[^:]+(?(c)(?<-c>:\d+)*):(\d+))
  • 本答案中的解决方案旨在作为一种工具来演示一些正则表达式语法,而不是要实现的实际答案
  • 在文件末尾,我们将粘贴一个数字列表,前面带有唯一分隔符。对于这个实验,附加的字符串是
    :1:2:3:4:5:6:7
    ,这是一种类似于使用整数表的著名数据库黑客的技术
  • 对于前两个解决方案,我们需要一个使用regex风格的编辑器,它允许递归(解决方案1)或自引用捕获组(解决方案2和3)。我想到了两个:Notepad++和EditPad Pro。对于第三种解决方案,我们需要一个支持平衡组的编辑器。这可能会限制我们使用EditPad Pro或Visual Studio 2013+
  • 输入文件:

    (?sm)(?=.*?pig)(?=((?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?:(?1)|[^:]+)(:\d+))?).*?\Kpig(?=.*?(?(2)\2):(\d+))
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # fail right away if pig isn't there
    
    (?=               # The Recursive Structure Lives In This Lookahead
    (                 # Group 1
       (?:               # skip one line 
          ^              
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        ) 
        (?:(?1)|[^:]+)   # recurse Group 1 OR match all chars that are not a :
        (:\d+)           # match digits
    )?                 # End Group 
    )                 # End lookahead. 
    .*?\Kpig                # get to pig
    (?=.*?(?(2)\2):(\d+))   # Lookahead: capture the next digits
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line 
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # for each line skipped, let Group 1 match an ever increasing portion of the numbers string at the bottom
       (?=             # lookahead
          [^:]+           # skip all chars that are not colons
          (               # start Group 1
            (?(1)\1)      # match Group 1 if set
            :\d+          # match a colon and some digits
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop everything we've matched so far
    pig               # match pig (this is the match!)
    (?=[^:]+(?(1)\1):(\d+))   # capture the next number to Group 2
    
    my cat pi g
    dog p ig
    my pig
    my cow
    my mouse
    
    :7:6:5:4:3:2:1
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line that doesn't have pig
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # Group 1 matches increasing portion of the numbers string at the bottom
       (?=             # lookahead
          .*           # get to the end of the input
          (               # start Group 1
            :\d+          # match a colon and some digits
            (?(1)\1)      # match Group 1 if set
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop match so far
    pig               # match pig (this is the match!)
    (?=.*(\d+)(?(1)\1))   # capture the next number to Group 2
    
    (?xm)                # free-spacing, multi-line
    (?<=                 # lookbehind
       \A                # 
       (?<c>               # skip one line that doesn't have pig
                           # The length of Group c Captures will serve as a counter
         ^                    # beginning of line
         (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
         (?:\r?\n)            # newline chars
       )                   # end skipper
       *                   # repeat skipper
       .*?                 # we're on the pig line: lazily match chars before pig
       )                # end lookbehind
    pig                 # match pig: this is the match
    (?=                 # lookahead
       [^:]+               # get to the digits
       (?(c)               # if Group c has been set
         (?<-c>:\d+)         # decrement c while we match a group of digits
         *                   # repeat: this will only repeat as long as the length of Group c captures > 0 
       )                   # end if Group c has been set
       :(\d+)              # Match the next digit group, capture the digits
    )                    # end lokahead
    
    假设我们正在搜索
    pig
    ,并希望将其替换为行号

    我们将使用它作为输入:

    my cat
    dog
    my pig
    my cow
    my mouse
    
    :1:2:3:4:5:6:7
    

    第一个解决方案:递归 支持的语言:除了上面提到的文本编辑器(Notepad++和EditPad Pro),这个解决方案应该在使用PCRE(PHP、R、Delphi)的语言中工作,在Perl中工作,在Python中使用Matthew Barnett的
    regex
    模块(未测试)

    递归结构存在于前瞻中,是可选的。它的工作是平衡左侧不包含
    pig
    的行和右侧的数字:将其视为平衡一个嵌套结构,如
    {{}}
    。。。除了左边是没有匹配线,右边是数字。关键是,当我们退出前瞻时,我们知道跳过了多少行

    搜索:

    (?sm)(?=.*?pig)(?=((?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?:(?1)|[^:]+)(:\d+))?).*?\Kpig(?=.*?(?(2)\2):(\d+))
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # fail right away if pig isn't there
    
    (?=               # The Recursive Structure Lives In This Lookahead
    (                 # Group 1
       (?:               # skip one line 
          ^              
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        ) 
        (?:(?1)|[^:]+)   # recurse Group 1 OR match all chars that are not a :
        (:\d+)           # match digits
    )?                 # End Group 
    )                 # End lookahead. 
    .*?\Kpig                # get to pig
    (?=.*?(?(2)\2):(\d+))   # Lookahead: capture the next digits
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line 
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # for each line skipped, let Group 1 match an ever increasing portion of the numbers string at the bottom
       (?=             # lookahead
          [^:]+           # skip all chars that are not colons
          (               # start Group 1
            (?(1)\1)      # match Group 1 if set
            :\d+          # match a colon and some digits
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop everything we've matched so far
    pig               # match pig (this is the match!)
    (?=[^:]+(?(1)\1):(\d+))   # capture the next number to Group 2
    
    my cat pi g
    dog p ig
    my pig
    my cow
    my mouse
    
    :7:6:5:4:3:2:1
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line that doesn't have pig
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # Group 1 matches increasing portion of the numbers string at the bottom
       (?=             # lookahead
          .*           # get to the end of the input
          (               # start Group 1
            :\d+          # match a colon and some digits
            (?(1)\1)      # match Group 1 if set
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop match so far
    pig               # match pig (this is the match!)
    (?=.*(\d+)(?(1)\1))   # capture the next number to Group 2
    
    (?xm)                # free-spacing, multi-line
    (?<=                 # lookbehind
       \A                # 
       (?<c>               # skip one line that doesn't have pig
                           # The length of Group c Captures will serve as a counter
         ^                    # beginning of line
         (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
         (?:\r?\n)            # newline chars
       )                   # end skipper
       *                   # repeat skipper
       .*?                 # we're on the pig line: lazily match chars before pig
       )                # end lookbehind
    pig                 # match pig: this is the match
    (?=                 # lookahead
       [^:]+               # get to the digits
       (?(c)               # if Group c has been set
         (?<-c>:\d+)         # decrement c while we match a group of digits
         *                   # repeat: this will only repeat as long as the length of Group c captures > 0 
       )                   # end if Group c has been set
       :(\d+)              # Match the next digit group, capture the digits
    )                    # end lokahead
    
    带有注释的自由间距版本:

    (?sm)(?=.*?pig)(?=((?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?:(?1)|[^:]+)(:\d+))?).*?\Kpig(?=.*?(?(2)\2):(\d+))
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # fail right away if pig isn't there
    
    (?=               # The Recursive Structure Lives In This Lookahead
    (                 # Group 1
       (?:               # skip one line 
          ^              
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        ) 
        (?:(?1)|[^:]+)   # recurse Group 1 OR match all chars that are not a :
        (:\d+)           # match digits
    )?                 # End Group 
    )                 # End lookahead. 
    .*?\Kpig                # get to pig
    (?=.*?(?(2)\2):(\d+))   # Lookahead: capture the next digits
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line 
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # for each line skipped, let Group 1 match an ever increasing portion of the numbers string at the bottom
       (?=             # lookahead
          [^:]+           # skip all chars that are not colons
          (               # start Group 1
            (?(1)\1)      # match Group 1 if set
            :\d+          # match a colon and some digits
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop everything we've matched so far
    pig               # match pig (this is the match!)
    (?=[^:]+(?(1)\1):(\d+))   # capture the next number to Group 2
    
    my cat pi g
    dog p ig
    my pig
    my cow
    my mouse
    
    :7:6:5:4:3:2:1
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line that doesn't have pig
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # Group 1 matches increasing portion of the numbers string at the bottom
       (?=             # lookahead
          .*           # get to the end of the input
          (               # start Group 1
            :\d+          # match a colon and some digits
            (?(1)\1)      # match Group 1 if set
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop match so far
    pig               # match pig (this is the match!)
    (?=.*(\d+)(?(1)\1))   # capture the next number to Group 2
    
    (?xm)                # free-spacing, multi-line
    (?<=                 # lookbehind
       \A                # 
       (?<c>               # skip one line that doesn't have pig
                           # The length of Group c Captures will serve as a counter
         ^                    # beginning of line
         (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
         (?:\r?\n)            # newline chars
       )                   # end skipper
       *                   # repeat skipper
       .*?                 # we're on the pig line: lazily match chars before pig
       )                # end lookbehind
    pig                 # match pig: this is the match
    (?=                 # lookahead
       [^:]+               # get to the digits
       (?(c)               # if Group c has been set
         (?<-c>:\d+)         # decrement c while we match a group of digits
         *                   # repeat: this will only repeat as long as the length of Group c captures > 0 
       )                   # end if Group c has been set
       :(\d+)              # Match the next digit group, capture the digits
    )                    # end lokahead
    
    替换:
    \3

    在中,请参见底部的替换。您可以使用前两行上的字母(删除一个空格以生成
    pig
    ),将第一个出现的
    pig
    移动到另一行,并查看这对结果的影响


    第二种解决方案:引用自身的组(“Qtax技巧”) 支持的语言:除了上面提到的文本编辑器(Notepad++和EditPad Pro),这个解决方案应该在使用PCRE(PHP、R、Delphi)的语言中工作,在Perl中工作,在Python中使用Matthew Barnett的
    regex
    模块(未测试)。通过将
    \K
    转换为先行词,将所有格量词转换为原子组(见下面几行的.NET版本),该解决方案很容易适应.NET

    搜索:

    (?sm)(?=.*?pig)(?:(?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*+.*?\Kpig(?=[^:]+(?(1)\1):(\d+))
    
    \2
    
    my cat
    dog
    my 3
    my cow
    my mouse
    
    :1:2:3:4:5:6:7
    
    (?m)(?<=\A(?<c>^(?:(?!pig)[^\r\n])*(?:\r?\n))*.*?)pig(?=[^:]+(?(c)(?<-c>:\d+)*):(\d+))
    
    .NET版本:回到未来

    .NET没有
    \K
    。在它的位置上,我们使用“回到未来”的后视(包含在比赛前跳过的前视的后视)。此外,我们需要使用原子群而不是所有格量词

    (?sm)(?<=(?=.*?pig)(?=(?>(?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*).*)pig(?=[^:]+(?(1)\1):(\d+))
    
    替换:

    (?sm)(?=.*?pig)(?:(?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*+.*?\Kpig(?=[^:]+(?(1)\1):(\d+))
    
    \2
    
    my cat
    dog
    my 3
    my cow
    my mouse
    
    :1:2:3:4:5:6:7
    
    (?m)(?<=\A(?<c>^(?:(?!pig)[^\r\n])*(?:\r?\n))*.*?)pig(?=[^:]+(?(c)(?<-c>:\d+)*):(\d+))
    
    输出:

    (?sm)(?=.*?pig)(?:(?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*+.*?\Kpig(?=[^:]+(?(1)\1):(\d+))
    
    \2
    
    my cat
    dog
    my 3
    my cow
    my mouse
    
    :1:2:3:4:5:6:7
    
    (?m)(?<=\A(?<c>^(?:(?!pig)[^\r\n])*(?:\r?\n))*.*?)pig(?=[^:]+(?(c)(?<-c>:\d+)*):(\d+))
    
    在中,请参见底部的替换。您可以使用前两行上的字母(删除一个空格以生成
    pig
    ),将第一个出现的
    pig
    移动到另一行,并查看这对结果的影响

    数字分隔符的选择

    在我们的示例中,数字字符串的分隔符
    非常常见,可能发生在其他地方。我们可以发明一个
    唯一的分隔符
    ,并稍微调整表达式。但是下面的优化更有效,让我们可以保留


    第二种解决方案的优化:反向数字串 与其按顺序粘贴数字,不如按相反的顺序使用:
    :7:6:5:4:3:2:1

    在我们的lookaheads中,这允许我们通过一个简单的
    *
    ,深入到输入的底部,并从那里开始回溯。因为我们知道我们在字符串的末尾,所以我们不必担心
    :digits
    是字符串另一部分的一部分。下面是如何做到这一点

    输入:

    (?sm)(?=.*?pig)(?=((?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?:(?1)|[^:]+)(:\d+))?).*?\Kpig(?=.*?(?(2)\2):(\d+))
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # fail right away if pig isn't there
    
    (?=               # The Recursive Structure Lives In This Lookahead
    (                 # Group 1
       (?:               # skip one line 
          ^              
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        ) 
        (?:(?1)|[^:]+)   # recurse Group 1 OR match all chars that are not a :
        (:\d+)           # match digits
    )?                 # End Group 
    )                 # End lookahead. 
    .*?\Kpig                # get to pig
    (?=.*?(?(2)\2):(\d+))   # Lookahead: capture the next digits
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line 
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # for each line skipped, let Group 1 match an ever increasing portion of the numbers string at the bottom
       (?=             # lookahead
          [^:]+           # skip all chars that are not colons
          (               # start Group 1
            (?(1)\1)      # match Group 1 if set
            :\d+          # match a colon and some digits
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop everything we've matched so far
    pig               # match pig (this is the match!)
    (?=[^:]+(?(1)\1):(\d+))   # capture the next number to Group 2
    
    my cat pi g
    dog p ig
    my pig
    my cow
    my mouse
    
    :7:6:5:4:3:2:1
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line that doesn't have pig
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # Group 1 matches increasing portion of the numbers string at the bottom
       (?=             # lookahead
          .*           # get to the end of the input
          (               # start Group 1
            :\d+          # match a colon and some digits
            (?(1)\1)      # match Group 1 if set
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop match so far
    pig               # match pig (this is the match!)
    (?=.*(\d+)(?(1)\1))   # capture the next number to Group 2
    
    (?xm)                # free-spacing, multi-line
    (?<=                 # lookbehind
       \A                # 
       (?<c>               # skip one line that doesn't have pig
                           # The length of Group c Captures will serve as a counter
         ^                    # beginning of line
         (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
         (?:\r?\n)            # newline chars
       )                   # end skipper
       *                   # repeat skipper
       .*?                 # we're on the pig line: lazily match chars before pig
       )                # end lookbehind
    pig                 # match pig: this is the match
    (?=                 # lookahead
       [^:]+               # get to the digits
       (?(c)               # if Group c has been set
         (?<-c>:\d+)         # decrement c while we match a group of digits
         *                   # repeat: this will only repeat as long as the length of Group c captures > 0 
       )                   # end if Group c has been set
       :(\d+)              # Match the next digit group, capture the digits
    )                    # end lokahead
    
    搜索:

    (?sm)(?=.*?pig)(?=((?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?:(?1)|[^:]+)(:\d+))?).*?\Kpig(?=.*?(?(2)\2):(\d+))
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # fail right away if pig isn't there
    
    (?=               # The Recursive Structure Lives In This Lookahead
    (                 # Group 1
       (?:               # skip one line 
          ^              
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        ) 
        (?:(?1)|[^:]+)   # recurse Group 1 OR match all chars that are not a :
        (:\d+)           # match digits
    )?                 # End Group 
    )                 # End lookahead. 
    .*?\Kpig                # get to pig
    (?=.*?(?(2)\2):(\d+))   # Lookahead: capture the next digits
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line 
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # for each line skipped, let Group 1 match an ever increasing portion of the numbers string at the bottom
       (?=             # lookahead
          [^:]+           # skip all chars that are not colons
          (               # start Group 1
            (?(1)\1)      # match Group 1 if set
            :\d+          # match a colon and some digits
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop everything we've matched so far
    pig               # match pig (this is the match!)
    (?=[^:]+(?(1)\1):(\d+))   # capture the next number to Group 2
    
    my cat pi g
    dog p ig
    my pig
    my cow
    my mouse
    
    :7:6:5:4:3:2:1
    
    (?xsm)             # free-spacing mode, multi-line
    (?=.*?pig)        # lookahead: if pig is not there, fail right away to save the effort
    (?:               # start counter-line-skipper (lines that don't include pig)
       (?:               # skip one line that doesn't have pig
          ^              # 
          (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
          (?:\r?\n)      # newline chars
        )   
       # Group 1 matches increasing portion of the numbers string at the bottom
       (?=             # lookahead
          .*           # get to the end of the input
          (               # start Group 1
            :\d+          # match a colon and some digits
            (?(1)\1)      # match Group 1 if set
          )               # end Group 1
       )               # end lookahead
    )*+               # end counter-line-skipper: zero or more times
    .*?               # match
    \K                # drop match so far
    pig               # match pig (this is the match!)
    (?=.*(\d+)(?(1)\1))   # capture the next number to Group 2
    
    (?xm)                # free-spacing, multi-line
    (?<=                 # lookbehind
       \A                # 
       (?<c>               # skip one line that doesn't have pig
                           # The length of Group c Captures will serve as a counter
         ^                    # beginning of line
         (?:(?!pig)[^\r\n])*  # zero or more chars not followed by pig
         (?:\r?\n)            # newline chars
       )                   # end skipper
       *                   # repeat skipper
       .*?                 # we're on the pig line: lazily match chars before pig
       )                # end lookbehind
    pig                 # match pig: this is the match
    (?=                 # lookahead
       [^:]+               # get to the digits
       (?(c)               # if Group c has been set
         (?<-c>:\d+)         # decrement c while we match a group of digits
         *                   # repeat: this will only repeat as long as the length of Group c captures > 0 
       )                   # end if Group c has been set
       :(\d+)              # Match the next digit group, capture the digits
    )                    # end lokahead
    
    替换:
    \2

    请参见中的替换

    第三个解决方案:平衡群体 此解决方案特定于.NET

    搜索:

    (?sm)(?=.*?pig)(?:(?:^(?:(?!pig)[^\r\n])*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*+.*?\Kpig(?=[^:]+(?(1)\1):(\d+))
    
    \2
    
    my cat
    dog
    my 3
    my cow
    my mouse
    
    :1:2:3:4:5:6:7
    
    (?m)(?<=\A(?<c>^(?:(?!pig)[^\r\n])*(?:\r?\n))*.*?)pig(?=[^:]+(?(c)(?<-c>:\d+)*):(\d+))
    

    (?m)(?),因为您没有指定vim中的文本编辑器:

    :%s/searched\u word/\=printf('%-4d',line('.'))/g


    但正如有人提到的,这不是SO的问题,而是超级用户的问题;)

    任何文本编辑器?其中一些根本不支持正则表达式。简单回答:不,正则表达式不替换正则表达式,也不做任何其他事情。他们只是定义了一个用于编程问题的模式。有关如何使用编辑器的问题属于“超级用户”。@Miller,因为操作是在Windows2问题上进行的。为什么你怀疑/知道windows上的OP,是基于之前的问题吗?如果OP是“代码>文件:DosGlob:<代码>