【问题标题】:BEGINNER: REGEX Match numeric sequence except where the word "CODE" exists on a lineBEGINNER: REGEX 匹配数字序列,除非在一行中存在单词“CODE”
【发布时间】:2009-12-23 20:49:14
【问题描述】:

我已经能够通过正则表达式跌跌撞撞地学习很长一段时间了,但是很遗憾,我无法帮助有需要的朋友。

我的“朋友”正在尝试匹配文本文件中符合以下条件的所有行:

  1. 只有 7 到 10 位数字(0123456 或 0123456789)
  2. 只有 7 到 10 位数字,然后是破折号,然后是另外两位数字(0123456-01 或 0123456789-01)
  3. 匹配上述任何除了,其中代码/代码或密码/密码要匹配的数字之前(例如“访问代码:16434629”或“密码 5253443-12")
  4. 编辑:只需要匹配的数字,不需要其他。

这是我见过的“他”给我的最糟糕的正则表达式:

^(?=.*?[^=/%:]\b\d{7,10}((\d?\d?)|(-\d\d))?\b)((?!Passcode|passcode|Code|code).)*$

...

问题:有没有办法使用简短的正则表达式来查找符合上述条件的所有行?

假设 PCRE。我的朋友提前谢谢你。 ;-)

顺便说一句 - 我无法在 stackoverflow.com 或 superuser.com 中找到可以准确回答此问题的任何其他问题。

编辑:我正在使用 Kodos Python 正则表达式调试器来验证和测试正则表达式。

【问题讨论】:

  • “完全是 7 到 10 位数字”是什么意思?您的意思是“正好是 7 个 10 位数字”吗?
  • 我觉得我最近说了很多,但为什么不分两步做:(1)​​跳过任何以“访问”或“密码”开头的行,然后(2)检查数字要求的其他行。另外,我不明白您的要求:您的 (1) 和 (2) andor 之间的连接是什么? (根据正则表达式,它是or,但我不确定。)
  • 如果一行有多个数字,而字代码只在两个数字之一之前,例如。 '0123456 访问代码:1234567'?这条线应该匹配还是不匹配?
  • 您使用什么工具或编程语言?
  • @Mark Byers: 1. “完全一样”是矫枉过正。简单地说,我只需要匹配 7 到 10 位数字。 2. PCRE 应该涵盖第二个问题。我使用的工具是 DLP,它使用正则表达式来查找敏感数据。

标签: regex regex-negation


【解决方案1】:
(?<!(?:[Pp]asscode|[Cc]ode).*)[0-9]{7,10}(?:-[0-9]{2})?

评论版本:

(?<!                 # Begin zero-width negative lookbehind. (Makes sure the following pattern can't match before this position)
(?:                  # Begin non-matching group
[Pp]asscode          # Either Passcode or passcode
|                    # OR
[Cc]ode              # Either Code or code
)                    # End non-matching group
.*                   # Any characters
)                    # End lookbehind
[0-9]{7,10}          # 7 to 10 digits
(?:                  # Begin non-matching group
-[0-9]{2}            # dash followed by 2 digits
)                    # End non-matching group
?                    # Make last group optional

编辑:评论讨论后的最终版本 -

/^(?!\D*(?:[Pp]asscode|[Cc]ode))\D*([0-9]{7,10}(?:-[0-9]{2})?)/

(导致第一个捕获缓冲区)

【讨论】:

  • 干得好!我唯一要添加的是:?(?:[Pp]asscode|[Cc]ode) 之后。
  • 评论版本很好。 //x 修饰符总是是你的朋友(虽然我会把它浓缩一点——“开始/结束不匹配的组”似乎有点过分了)。
  • @Dav:当我在 perl 中使用您的正则表达式时:if(m{(?
  • “过度评论”主要是因为在 SO 上发帖。不是我在自己的代码中使用的那种评论。 :) 但我认为,信息越多越好,因为没有假设任何特定读者可能知道什么。
  • 哦,bzabhi - 您可能需要在后面修改.*;您对密码短语位的“先于”的定义有点模糊。
【解决方案2】:

你可以通过一个讨厌的正则表达式来获得帮助......

... 或者您可以使用两个 simple 正则表达式。一种匹配您想要的,另一种过滤您想要的。更简单,更易读。

你想读哪一本?

$foo =~ /(?<!(?:[Pp]asscode|[Cc]ode).*)[0-9]{7,10}(?:-[0-9]{2})?/

$foo =~ /\d{7,10}(-\d{2})?/ and $foo !~ /(access |pass)code/i;

编辑:不区分大小写。

【讨论】:

  • 感谢您的评论。我坚持我想的讨厌的解决方案。虽然你是对的——在这种情况下有两个更好——但它不会安抚那些被称为“股东”的高级生命。这是由于具有不接受“过滤器”正则表达式的软件解决方案。你有一个例子吗?我可以试一试,但到目前为止,在测试更简单的案例时,它的效果并不好。
  • 你的例子就是我想要的。术语“它” = 使用两个简单的正则表达式。
  • 第一个版本不是PCRE,第二个版本没有做他想做的事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
相关资源
最近更新 更多