正则表达式仅在前面没有时替换

Posted

技术标签:

【中文标题】正则表达式仅在前面没有时替换【英文标题】:Regex to replace only if not preceded by 【发布时间】:2015-05-10 22:39:26 【问题描述】:

对于我公然缺乏正则表达式知识,我深表歉意,我知道这里会出现很多问题,但我可能会连续几个小时尝试,但我无法弄清楚这一点。 基本上我要做的是替换字符串中所有出现的 6 位数字(带或不带连字符)。但是,如果前面有某些单词,我不希望替换数字。

这个Regular expression to match a line that doesn't contain a word? 解决方案接近我正在寻找的,但我似乎无法以适合我要求的方式使用它。

我需要如下: 对于字符串:

“用户于 2014 年 5 月 23 日向账户 123456 支付了 43 英镑,支票 123456 交易:123456。”

我只想替换前面没有“支票”或“交易:”的 6 位数字。我一直在尝试如下:

\b[0-9]2-?[0-9]2-?[0-9]2\b 

(这将替换所有 6 位数字)

使用这个How do you replace a match, using regex, only if it is not preceded by a given character? 答案,我试过了

(^cheque\s[0-9]2-?[0-9]2-?[0-9]2\b) 

(请注意,我首先尝试使用我希望转义的单词之一,然后再包含其他单词。) 这不会替换任何 6 位数字。

经过反复试验,我发现了

(cheque\s+[0-9]2-?[0-9]2-?[0-9]2\b) 

将替换单词 check 后跟一个 6 位数字,所以我到了那里 - 但我需要否定这个(交易后跟 6 位数字)并替换为 6 位数字 不是前面有这些词。

这个How to negate the whole regex? 答案有助于弄清楚如何否定表达式,但尽我所能,我找不到如何让它适合我的情况。我试过了

^(?!(?:((transaction\s+[0-9]2-?[0-9]2-?[0-9]2\b) )|((cheque\s+[0-9]2-?[0-9]2-?[0-9]2\b) ))$).*$

但这替换了整个字符串!

非常感谢您对此的任何帮助。

谢谢你。

【问题讨论】:

请澄清。您使用什么语言?此外,如果您正在运行标准的“全部替换”,则不能不替换某些匹配项。您可以将正则表达式更改为根本不匹配它们(满足要求)或迭代匹配并使用进一步的代码检查它们。匹配它们是否足以满足您的需求? 只有在你的正则表达式引擎支持negative look-behinds时才能这样做。 感谢您的快速回复!我正在使用 c#,但我坚持使用 Visual Studio 2005。 我需要替换那些没有'check'的 【参考方案1】:

试试这个:

(?<!(?:cheque|transaction:)\s*)\d2-?\d2-?\d2\b

解释:

(?&lt;! ... ) Negative lookbehind assertion(匹配前面没有的任何东西) (?:cheque|transaction:)\s* 非捕获组“支票”或“交易:”后跟任意数量的空格 \d2-?\d2-?\d2\b 六位数字可能连字符,以单词边界结尾

【讨论】:

非常感谢 tzaman。我昨晚想通了,您的解决方案与我想出的非常接近:【参考方案2】:

非常感谢@tzaman 的回答 - 经过一番摸索、反复试验,以及一位同事的意见,我昨晚想通了,并想出了以下内容。 (我会添加很多案例,因为用户可能会输入支票号码/支票号码等内容,但它们只是额外的条件 - 以下是解决问题的主要部分。)

(?<!                                  
  (
    (cheque\s0,:0,1\s0,)
    |
    (transaction\s0,:0,1\s0,)
  )
)
(
  [0-9]6
  |
  ([0-9]2[0-9]2-[0-9]2)
)

再次感谢。

【讨论】:

以上是关于正则表达式仅在前面没有时替换的主要内容,如果未能解决你的问题,请参考以下文章

在 presto 中使用正则表达式仅在最后一个斜杠前面有一个字符时才删除它

教你notepad++用正则表达式替换掉各行逗号前面内容

正则表达式替换文本,除非它前面有反斜杠而不使用后视

PostgreSQL 正则表达式用条件替换函数

使用正则表达式替换命令在文件名字符串中小于 10 的数字前面插入前导零

python 正则表达式参数替换