只有在没有前面的情况下才能替换正则表达式

时间:2015-03-09 16:59:48

标签: regex

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

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

我需要的是: 对于字符串:

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

我希望只替换不在“check”或“transaction:”之前的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) ))$).*$

但这取代了整个字符串!

非常感谢任何帮助。

感谢你。

2 个答案:

答案 0 :(得分:11)

试试这个:

(?<!(?:cheque|transaction:)\s*)\d{2}-?\d{2}-?\d{2}\b

说明:

  • (?<! ... )否定的背后断言(匹配任何不以此为先的内容)
  • (?:cheque|transaction:)\s*非捕获组“check”或“transaction:”后跟任意数量的空格
  • \d{2}-?\d{2}-?\d{2}\b可能连字符的六位数字,以字边界结尾

答案 1 :(得分:0)

非常感谢@tzaman的回答 - 有些头疼,试错,以及我昨晚想出来的一位同事的意见,并提出了以下建议。 (我会添加很多案例,因为用户可能会输入支票编号/支票编号等等,但它们只是额外的条件 - 下面是解决问题的主要部分。)

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

再次感谢。