如何限制正则表达式中的可选空格匹配

时间:2018-09-21 19:16:11

标签: regex whitespace powergrep

是的。 (是的,另一个正则表达式问题)。

除了具体示例外,不确定最清晰的描述方式。

示例文字:

  1. 4444 4444 4444 4444
  2. 4444444444444444
  3. 44 44 44 44 44 44 44 44
  4. 4444-4444-4444-4444
  5. 4444(多个空格)4444(多个空格)4444(多个空格)4444
  6. 0.4444444444444444
  7. 0.4444 4444 4444 4444

我需要构建仅匹配1、2和4的正则表达式。要求13-16位数字,破折号和空格(可选),但仅在单个空格且不超过3个的情况下。

这显然与CC信息搜索有关,并且我已经进行了大量研究,发现了很多示例,这些示例找到了大多数,全部或全无的匹配项,但是没有什么可以消除上述3和5之类的过多误报。我正在使用PowerGREP 5,已经阅读了https://www.regular-expressions.info/tutorial.html上的整个教程,但无法弄清楚如何限制整体匹配中可选空格的数量。即:如果我将空格设为可选,则“ 1 2 3 4 5 6 7 8 9”与“ 123 456 789”匹配。本质上,如果检测到3个以上的空格/破折号,我希望正则表达式结束匹配搜索。

旁注:我在一家处理大量日历数据的公司工作,因此使用许多“ 1 2 3 4 5 6 7 8 ...”样式的文本字符串来抓取大量驱动器会产生大量错误匹配,即使我花时间将搜索调整为包含CC的模式。

任何帮助将不胜感激。

我找到的最接近的是:

\b(?:\d[ -]*?){13,16}\b

哪个可以按预期截取任何13-16位数字(允许在中间用破折号或空格),但它也会匹配“ 1 2 3 4 5 6 7 8 9 10 11”,这显然没有帮助。

所有包含CC的正则表达式正则表达式(如果包含空格/破折号,都将找不到有效号码):(但会找到英国电话号码,呵呵):

\b(?:4[0-9]{12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})\b

因此,我然后尝试用(?:\ d [-] *?)替换上面的任何[0-9]字符类实例,这将找到带有破折号/空格的有效CC,但它也匹配所有的“ 1 2 3 4 5 6 7 8 9 10 11“类型的误报。

我对regex非常陌生,因此,如果我犯了一个巨大的noob错误,请随时为我指出正确的方向。谢谢!

编辑:

仅将较大的连续字符串部分替换为(?:\ d [-]?)的[0-9]似乎与我所需要的非常接近。像以前一样使用相同的驱动器,只有311个匹配项,并且找到了所有3个肯定的文件,我只能忍受308个错误匹配项,但是我想像还有一种更好的方法可以做到这一点。而且它仍然匹配具有3个以上定界符的13至16位数字的字符串...

当前正则表达式:

\b(?:4(?:\d[ -]?){12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)(?:\d[ -]?){12}|3[47](?:\d[ -]?){13}|3(?:0[0-5]|[68][0-9])(?:\d[ -]?){11}|6(?:011|5[0-9]{2})(?:\d[ -]?){12}|(?:2131|1800|35\d{3})(?:\d[ -]?){11})\b

1 个答案:

答案 0 :(得分:3)

由于您似乎希望第四个数字后跟一个破折号,一个空格或什么都不是,因此最简单的方法就是使用

^(\d{4}[\s\-]?){3}\d{4}$

这将满足您的书面条件,但可以使用类似1234-5678 9012的混合形式。如果不可接受,您可以使用正向前行来验证模式是否重复相同

^(?=(\d{4}){3}|(\d{4}-){3}|(\d{4}\s){3})(\d{4}[\s-]?){3}\d{4}$

第一个正则表达式

  • 从字符串的开头开始:^
  • 查找四位数(0-9),并可选地后面跟空格或破折号,并重复此模式3次:(\d{4}[\s\-]?){3}
  • 然后是另外四个数字和字符串的结尾:\d{4}$

仅从第二个正则表达式中进行回顾:(?=(\d{4}){3}|(\d{4}-){3}|(\d{4}\s){3})

  • 在模式开始捕获任何内容之前,我们再次从字符串的开头开始,并查看前三个重复的模式,并确保两者之间的分隔符相同。

我看到在您的正则表达式示例中,您希望允许13-16位数字,而我的专用于16位数字。对于13-16位数字,您需要确定这些分隔符的位置。只要它们只有三个并且不重复,它们可以在任何地方吗?我还看到您正在使用单词边界,所以我猜您正在尝试匹配子字符串。您可以这样做,但是会有些困难。破折号和空格都是单词边界,因此您可能会得到一些误报而没有环顾四周。

就集成到CC正则表达式而言,您正在懒惰地匹配无限数量的破折号或空格;您只需要?而不是*?。如果您需要更大的灵活性来保留这些空格/数字,同时又要限制它们,那么我可能会使用负的正则表达式进行验证。