我们正在为电子邮件进行数据丢失防护,但是问题是当人们多次回复电子邮件时,有时信用卡号或帐号会多次出现。
我们如何才能使Java Regex每个字符串仅匹配一次。
因此,例如,我们使用以下正则表达式捕获与2个字母后跟5或6个数字匹配的帐号。无论哪种情况,它都将省略CR。
\b(?!CR)(?!cr)[A-Za-z]{2}[0-9]{5,6}\b
Run Code Online (Sandbox Code Playgroud)
我们如何找到它:
CX12345
CX14584
JB145888
JD748452
CX12345 (Ignore as its already found it above)
LM45855
Run Code Online (Sandbox Code Playgroud)
唯一的字符串出现可以匹配
<STRING_PATTERN>(?!.*<STRING_PATTERN>) // Find the last occurrence
(?<!<STRING_PATTERN>.*)<STRING_PATTERN> // Find the first occurrence, only works in regex
// that supports infinite-width lookbehind patterns
Run Code Online (Sandbox Code Playgroud)
其中<STRING_PATTERN>是人们所搜索的唯一出现的模式。请注意,两者都可以与 .NET 正则表达式库配合使用,但大多数其他库通常不支持第二个(只有 PyPi Pythonregex库和 JavaScript ECMAScript 2018 正则表达式支持它)。请注意,.默认情况下不匹配换行符,因此您需要传递像 DOTALL 这样的修饰符(在大多数库中,您可以在(?s)模式内添加修饰符(仅在 Ruby 中(?m)这样做相同),或者使用传递给regex 编译方法。有关此内容的更多信息,请参阅如何在正则表达式中匹配多行中的任何字符?
您似乎需要这样的正则表达式:
/\b((?!CR|cr)[A-Za-z]{2}\d{5,6})\b(?![\s\S]*\b\1\b)/
Run Code Online (Sandbox Code Playgroud)
正则表达式演示可在此处获取
细节:
\b- 前导词边界((?!CR|cr)[A-Za-z]{2}\d{5,6})- 第 1 组捕获
(?!CR|cr)- 接下来的两个字符不能是CRor cr,即否定的前瞻检查[A-Za-z]{2}- 2 个 ASCII 字母\d{5,6}- 5 至 6 位数字\b- 尾随字边界(?![\s\S]*\b\1\b)[\s\S]*- 如果有任何 0+ 字符 ( ) 后跟字边界 ( \b)、捕获到组 1 中的相同值(带有\1反向引用)和尾随字边界,则负向前瞻会导致匹配失败。