仅当整行与正则表达式匹配时才替换模式

时间:2021-11-04 19:26:45

I am sure there is a trivial solution to this question but I can't seem to get it right:
I want to replace a specific pattern in a line only if the whole line matches the regex.

我确信这个问题有一个简单的解决方案,但我似乎无法做到正确:我想只在整行与正则表达式匹配时才替换一行中的特定模式。

So in my case three pipes | should be replaced by underscores _ only if the whole line is numbers and pipes:

所以在我的情况下三个管道|应该用下划线替换_仅当整行是数字和管道时:

|||10|||-80|||-120|||400           ---> replace
|||10|||asdf|||-120|||400          ---> don't replace
|||10|||-80|||400                  ---> replace
|||10|||-80|||-120|||400|||test    ---> don't replace

Expected result:

___10___-80___-120___400
|||10|||asdf|||-120|||400
___10___-80___400
|||10|||-80|||-120|||400|||test

My attempts:

\|\|\|(?=\-?\d+)

replaces the pipes if followed by numbers as expected but of course also in the "invalid" lines

如果按照预期后跟数字,则替换管道,但当然也在“无效”行中

^(\|\|\|\-?\d+){1,}$

matches the whole line and therefore I can't replace only the pipes

匹配整条线,因此我不能只更换管道

I understand why my patterns don't work and perhaps I have to simply do it with two passes but it feels like this should totally be possible.

我理解为什么我的模式不起作用,也许我只需要通过两次通过,但感觉这应该是完全可能的。

1 个解决方案

#1


5  

Without more details, it seems you can use

没有更多细节,似乎你可以使用

(?<=^(?:\|{3}-?\d+)*)\|{3}(?=-?\d+(?:\|{3}-?\d+)*$)

Or, if you need to process lines in a larger string:

或者,如果您需要处理更大的字符串中的行:

(?m)(?<=^(?:\|{3}-?\d+)*)\|{3}(?=-?\d+(?:\|{3}-?\d+)*\r?$)

See the regex demo.

请参阅正则表达式演示。

仅当整行与正则表达式匹配时才替换模式

Details:

  • (?<=^(?:\|{3}-?\d+)*) - a positive lookbehind that requires that, immediately to the left of the current location, there is:
    • ^ - start of string anchor
    • ^ - 字符串锚点的开始

    • (?:\|{3}-?\d+)* - zero or more sequences of 3 |s followed with an optional - (-?) and then 1 or more digits
    • (?:\ | {3} - ?\ d +)* - 零个或多个3 | s序列,后跟可选 - ( - ?),然后是1个或多个数字

  • (?<= ^(?:\ | {3} - ?\ d +)*) - 一个正向的lookbehind,要求立即在当前位置的左侧,有:^ - 字符串锚点的开始(?:\ | {3} - ?\ d +)* - 零个或多个3 | s序列,后跟可选 - ( - ?),然后是1个或多个数字

  • \|{3} - 3 pipes
  • \ | {3} - 3根管子

  • (?=-?\d+(?:\|{3}-?\d+)*$) - a positive lookahead that requires that, immediately to the right of the current location, there is
    • -?\d+ - an optional - and then 1+ digits
    • - ?\ d + - 可选 - 然后是1+位数

    • (?:\|{3}-?\d+)* - 0 or more sequences of 3 |s + an optional - and then 1+ digits
    • (?:\ | {3} - ?\ d +)* - 0个或多个序列3 | s +一个可选 - 然后是1+个数字

    • $ - end of string anchor.
    • $ - 字符串锚点结束。

  • (?= - ?\ d +(?:\ | {3} - ?\ d +)* $) - 一个积极的前瞻,需要立即在当前位置的右边,有 - ?\ d + - 一个可选的 - 然后1+位数(?:\ | {3} - ?\ d +)* - 0个或多个序列3 | s +一个可选 - 然后1+个数字$ - 字符串锚点结束。

C#:

var res = Regex.Replace(s, @"(?<=^(?:\|{3}-?\d+)*)\|{3}(?=-?\d+(?:\|{3}-?\d+)*$)", "___", RegexOptions.ECMAScript);

The RegexOptions.ECMAScript flag is used to make \d only match ASCII digits.

RegexOptions.ECMAScript标志用于使\ d仅匹配ASCII数字。

#1


5  

Without more details, it seems you can use

没有更多细节,似乎你可以使用

(?<=^(?:\|{3}-?\d+)*)\|{3}(?=-?\d+(?:\|{3}-?\d+)*$)

Or, if you need to process lines in a larger string:

或者,如果您需要处理更大的字符串中的行:

(?m)(?<=^(?:\|{3}-?\d+)*)\|{3}(?=-?\d+(?:\|{3}-?\d+)*\r?$)

See the regex demo.

请参阅正则表达式演示。

仅当整行与正则表达式匹配时才替换模式

Details:

  • (?<=^(?:\|{3}-?\d+)*) - a positive lookbehind that requires that, immediately to the left of the current location, there is:
    • ^ - start of string anchor
    • ^ - 字符串锚点的开始

    • (?:\|{3}-?\d+)* - zero or more sequences of 3 |s followed with an optional - (-?) and then 1 or more digits
    • (?:\ | {3} - ?\ d +)* - 零个或多个3 | s序列,后跟可选 - ( - ?),然后是1个或多个数字

  • (?<= ^(?:\ | {3} - ?\ d +)*) - 一个正向的lookbehind,要求立即在当前位置的左侧,有:^ - 字符串锚点的开始(?:\ | {3} - ?\ d +)* - 零个或多个3 | s序列,后跟可选 - ( - ?),然后是1个或多个数字

  • \|{3} - 3 pipes
  • \ | {3} - 3根管子

  • (?=-?\d+(?:\|{3}-?\d+)*$) - a positive lookahead that requires that, immediately to the right of the current location, there is
    • -?\d+ - an optional - and then 1+ digits
    • - ?\ d + - 可选 - 然后是1+位数

    • (?:\|{3}-?\d+)* - 0 or more sequences of 3 |s + an optional - and then 1+ digits
    • (?:\ | {3} - ?\ d +)* - 0个或多个序列3 | s +一个可选 - 然后是1+个数字

    • $ - end of string anchor.
    • $ - 字符串锚点结束。

  • (?= - ?\ d +(?:\ | {3} - ?\ d +)* $) - 一个积极的前瞻,需要立即在当前位置的右边,有 - ?\ d + - 一个可选的 - 然后1+位数(?:\ | {3} - ?\ d +)* - 0个或多个序列3 | s +一个可选 - 然后1+个数字$ - 字符串锚点结束。

C#:

var res = Regex.Replace(s, @"(?<=^(?:\|{3}-?\d+)*)\|{3}(?=-?\d+(?:\|{3}-?\d+)*$)", "___", RegexOptions.ECMAScript);

The RegexOptions.ECMAScript flag is used to make \d only match ASCII digits.

RegexOptions.ECMAScript标志用于使\ d仅匹配ASCII数字。