【问题标题】:Match digits or alphanumeric of variable length in a regular expression匹配正则表达式中可变长度的数字或字母数字
【发布时间】:2014-03-07 07:31:38
【问题描述】:

我正在使用 Perl 从文本文件中提取某些行。这些行都以十一个字符代码开头,例如

 XXX   YXXXZZXX  Data to get

其中X 总是一个数字,Y 可以是字母数字或缺失,Z 可以是字母数字(特别是它可以是 A 或数字 0-9。另一个问题是,有时这个字符如果Z 部分是三个字符而不是 2 个字符,则代码可以是 12 个字符。

 XXX   YXXXZZZXX  Data to get

我可以在前三个 XY 中硬编码,但我需要代码对 Z 灵活。我基本上需要将Z 存储为ID 变量。就上下文而言,前三个字母表示“要获取的数据”是答案的调查中的问题编号。所以假设我正在寻找问题72 然后(假设Y 不缺少Q72)我正在使用的匹配代码是

 if(m{^072(\s+)YXXX(d\{2,3})(\d{2})(\s+)(.+)}){
      my $id = $2;
      my $Data = $5
 }

这似乎解决了 11 对 12 个字符的问题,因为 11 个字符代码中的最后一个 XX 始终只有两个字符长。如果代码长度为 12 个字符,则唯一增加的部分是 Z 部分。所以这应该能够捕获所有 2 位和 3 位数字的 id(如果我错了,请纠正我)。

问题在于,有时 id 将是 AA(从不 AAA),我需要使代码足够灵活,以便对所有 2 位和 3 位代码以及潜在的 @ 执行 if 语句987654340@身份证。

我试过了

 if(m{^072(\s+)YXXX(.{2,3})(\d{2})(\s+)(.+)}){
      my $id = $2;
      my $Data = $5
 }

但我不认为它工作得很好。我认为. 可能太灵活了。关于正确方法的任何建议?谢谢!

【问题讨论】:

  • 你能举例说明你想匹配和提取什么吗?
  • 072 C001AA00 Data to get072 C0010300 Data to get072 C00110200 Data to get。第一个 ID 是AA,第二个 ID 是 03,第三个 ID 是 102。谢谢。
  • 最后两个 XX 总是 2 位数吗?如果是这样,您可以离开 .{2,3} 并使用 \d{2} 代替最后一个 XX。这将解决“过于灵活”的部分。另请注意,如果您也不需要它们,则不需要在 \s+\d+ 周围使用括号。你应该可以使用^072\s+YXXX(.{2,3})\d+\s+(.+),然后得到my $id = $1; my $Data = $2
  • 嗨@Jerry。是的,XX 总是 2 位数长。我在输入上面的代码时出错了。我已经更改了帖子以反映这一点。谢谢!

标签: regex perl


【解决方案1】:

一般模式:要获取的 XXX YXXXZZXX 数据

其中 X 始终是数字,Y 可以是字母数字或缺失,Z 可以是 字母数字(具体可以是 A 或数字 0-9。另一个 皱纹是有时这个字符代码可以是12个字符 如果 Z 部分是三个字符而不是 2 个字符,则为 long。

试图翻译你的规格,我想出了这个:

[\d]{3}\s*[\d\w]?[\d]{3}[A\d]{2,3}[\d]{2}\s*(.+)

演示:

http://regexr.com?38ejs


更新:

还有另一个演示(包含所有测试用例 + 匹配组):

http://rubular.com/r/6asYzHqi5P

072 C001AA00 数据得到 1

072 C0010300 获取2的数据

072 C00110200 数据得到3

【讨论】:

    【解决方案2】:

    也许以下内容会有所帮助:

    use strict;
    use warnings;
    
    while (<DATA>) {
        my ( $id, $data ) = /^072\s+\w{4}(\w{2,3})\w{2}\s+(.+)/;
        print "ID: $id; Data: $data\n";
    }
    
    __DATA__
    072 C001AA00 Data1 to get
    072 C0010300 Data2 to get
    072 C00110200 Data3 to get
    

    输出:

    ID: AA; Data: Data1 to get
    ID: 03; Data: Data2 to get
    ID: 102; Data: Data3 to get
    

    【讨论】:

    • 谢谢,但是,对于很多不同的问题,我必须这样做,而且这部分代码已经嵌套得很深,所以我希望有一种方法可以一次性完成只需更改我的匹配命令即可。有没有比使用(.{2,3}) 更好的方法来查找AA0-9
    • @MarkClements - 查看我修改后的答案。
    • 哦,我没有意识到\w 会捕获数字以及字母数字。我认为它只会捕获字母数字字符。我误会了什么?
    • @MarkClements - \w (for word) 匹配字母数字字符和下划线“_”。
    • @MarkClements 字母数字是用于字母和数字的术语。字母表示字母,数字表示数字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 2011-06-17
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多