【问题标题】:RegEx Conditional Prefix & Suffix to Known-Length Internal Digits已知长度内部数字的正则表达式条件前缀和后缀
【发布时间】:2012-12-21 11:21:36
【问题描述】:

我已经搜索了条件前缀的答案,但我没有找到答案。我预计我错过了一些简单的东西,但我一直没有成功。

我希望用一条正则表达式匹配所有这些系列:

以下是逻辑部分:

  1. (可能是 2 个字母前缀,可能是单词边界)
  2. (七位数)
  3. (可能是 2 个字符后缀 [第一个始终为字母、第二个字母或 number],可能是单词边界)

匹配示例(字母和数字任意):

1234567

1234567B1

1234567A2

1234567AA

AA1234567

AA1234567A1

AA1234567

AA1234567BB

拒绝:

12345678

/1234567

-1234567

:1234567

01234567

AB12345678AB


我的尝试:

我一直尝试在那里分组。匹配七个连续数字显然很简单'[0-9]{7}',但我很难匹配可选组中的插入符号 NOT 字符。

例如,如果我执行 '[^\d]?[0-9]{7}' 希望匹配一个可能有前缀的七位数字,但该前缀不能是数字,我的匹配项没有前缀失败(即只是一个七位数的字符串)。

显然,我是 regex 的新手,因此感谢您提供任何帮助。


编辑谢谢大家!这些中的每一个似乎都会产生与我的实际测试文件非常接近的结果,我将不得不测试一下,但目前看起来我们有多个正确和有效的答案。

【问题讨论】:

  • 您是想在一行的中间找到这些字符串,还是在一行中单独查找这些字符串?
  • 他们可以在任何地方——中间的或他们自己的。
  • 那您能否提供更具代表性的样本输入和预期输出?
  • 我不确定我是否理解您对更具代表性的输出的要求——正如我所说,这些字母数字字符串随机分散在整个文本文件中。没有任何图案。
  • 然后简单地显示一个小输入文件,其中包含分散在其中的字符串以及在该文件上运行所需工具后想要获得的输出。我敢肯定,在您的脑海中,您确切地知道自己想要什么,但它是模棱两可的,因此我们很难提供准确的答案。

标签: regex bash sed grep


【解决方案1】:

这可能对你有用(GNU sed):

sed -nr '/^([a-z]{2})?[0-9]{7}([a-z][a-z0-9])?$/Ip' file

【讨论】:

    【解决方案2】:
    perl -lnE  'print if m{
            \A                        # Beginning of string
            (?:  [a-z]{2} | \b )?     # (Maybe 2 Letter Prefix, Maybe word boundary)
            \d{7}                     # (seven digits)
            (?: [a-z][a-z\d] | \b )?  # (Maybe 2 character suffix [first always letter, second letter or number], maybe word boundary)
            \z                        # End of string
        }xmsi' < file
    

    【讨论】:

      【解决方案3】:
      $ awk '/^([[:alpha:]]{2})?[[:digit:]]{7}([[:alpha:]][[:alnum:]])?$/' file
      1234567
      1234567B1
      1234567A2
      1234567AA
      AA1234567
      AA1234567A1
      AA1234567
      AA1234567BB
      $ awk '!/^([[:alpha:]]{2})?[[:digit:]]{7}([[:alpha:]][[:alnum:]])?$/' file
      12345678
      /1234567
      -1234567
      :1234567
      01234567
      AB12345678AB
      

      【讨论】:

      • 我不希望分两步进行。我可以使用一条线(以上两者之间没有管道)吗?
      • 上面没有管道。我展示了 2 个单独的命令 - 一个用于打印与 RE 匹配的行,另一个用于打印与 RE 不匹配的行,以便您可以与发布的示例输出进行比较。您想要打印选定的行和拒绝的行吗?如果是这样,您希望将文件分开还是什么?你想要整行输出还是只输出匹配的字符串?
      【解决方案4】:

      使用这个正则表达式^[a-zA-Z]{0,2}\d{7}([a-zA-Z][a-zA-Z\d])?$

      ^ string begin
      
      [a-zA-Z]{0,2}Maybe 2 Letter Prefix, Maybe word boundary
      
      \d{7} seven digits
      
      ([a-zA-Z][a-zA-Z\d])?Maybe 2 character prefix [first always letter, second letter or number], maybe word boundary
      
      $ string end
      

      【讨论】:

      • 将 ^ 和 $ 替换为 \b(单词边界)。否则“wordAA1234567B2word”无法匹配
      • \b[a-zA-Z]{0,2}\d{7}([a-zA-Z][a-zA-Z\d])?\b 匹配 / 1234567 -1234567 :1234567
      • 使用字符类而不是显式字符范围,因为您不知道 OP 语言环境,因此,例如,[a-zA-Z] 可能与 [[:alpha:] 不匹配相同的字符].
      • 感谢您对内部部分的解释。它绝对可以帮助我理解发生了什么。我会在测试后报告。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多