代码之家  ›  专栏  ›  技术社区  ›  Patrick

正则表达式教程,我如何改进它

  •  1
  • Patrick  · 技术社区  · 16 年前

    今天早些时候,我需要一个实用函数来从文件中删除一些数据,并为此编写了一个惊人的常规表达式。输入是一个包含很多行的文件,格式如下:

    <address> <11 * ascii character value>      <11 characters>
    00C4F244  75 6C 74 73 3E 3C 43 75 72 72 65  ults><Curre
    

    我想去掉结尾的11个字符之外的所有内容,并使用以下表达式:

    "^[0-9A-F+]{8}[\\s]{2}[0-9A-F\\s]{34}"
    

    2:找到一种方法,在单个ascii值上重复匹配,后跟空格(例如“75”=[0-9A-F]{2}[\s]{1}?),并重复11次,而不是抓取34个字符。

    编辑:谢谢各位,这就是我想要的:

    "(?:^[0-9A-F]{8}  )(?:[0-9A-F]{2} ){11} (.*)"
    

    但愿我能把你们中的不止一个变成绿色。

    6 回复  |  直到 16 年前
        1
  •  5
  •   Gumbo    16 年前

    由于文件具有固定格式,因此可以使用此正则表达式仅匹配最后11个字符。

    ^.{44}(.{11})
    
        2
  •  2
  •   kmkaplan    16 年前

    最后十一项是:

    ...........$
    

    或:

    .{11}$
    

    匹配十六进制字节+空格并重复11次:

    ([0-9A-Fa-f]{2} ){11}
    
        3
  •  1
  •   chaos    16 年前

    paren用于分组和提取。如何检索它取决于您的语言上下文,但现在在初始模式之后,某种$1设置为everything。

    2) ^[0-9A-F+]{8}[\s]{2}(?[0-9A-F\s]){11}\s(.*

    (?:)是分组而不提取。因此(?[0-9A-F\s]){11}将其中的子模式视为一个单元,并查找重复11次的子模式。

    顺便说一下,我假设这里有PCRE。

        4
  •  0
  •   user68610    16 年前

    地址和ascii字符值均为十六进制,因此:

        5
  •  0
  •   Sylverdrag    16 年前

    与该行末尾匹配的是

    .{11}$
    

    为了只匹配结尾,你可以使用正面的后视。

    "(?<=(^[0-9A-F+]{8}[\\s]{2}[0-9A-F\\s]{34}))(.*?)$"
    

    (?<=..)定义了在可能进行匹配之前必须满足的条件。

    我的时间有点短,但是如果你在网上查找任何包含单词“regex”和“lookback”的教程,你会发现很好的东西(如果regex教程包含lookahead/behind,它通常会非常完整和高级)。

    Regex designer .

        6
  •  0
  •   Brad Gilbert    16 年前

    如果你正在使用 Perl ,你也可以使用 unpack() ,以获取每个元素。

    my @data;
    
    open my $fh, '<', $filename or die;
    for my $line(<$fh>){
      my($address,@list) = unpack 'a8xx(a2x)11xa11', $line;
      my $str = pop @list;
    
      # unpack the hexadecimal bytes
      my $data = join '', map { pack 'H2',$_ } @list;
    
      die unless $data eq $str;
    
      push @data, [$address,$data,$str];
    }
    close $fh;
    

    我还继续将11个十六进制代码转换回字符串,使用 pack() .