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

时间:2009-02-24 14:51:40

标签: regex

我今天早些时候需要一个utililty函数来从文件中删除一些数据并编写一个适当的常规表达式来完成它。输入是一个包含许多行的文件,格式为:

<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}"

这与我不想要的位相匹配,然后我从原始字符串中删除了这些位。我想看看你是如何做到的,但我无法工作的特定领域是:

1:让正则表达式引擎返回我想要的字符,而不是我没有的字符和

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

再看一遍,最容易做的就是匹配每个输入行的最后11个字符,但这不是很灵活,为了学习正则表达式,我想看看你怎么能匹配来自序列的开始。

编辑:谢谢大家,这就是我想要的:

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

希望我能让一个人变成绿色。

6 个答案:

答案 0 :(得分:5)

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

^.{44}(.{11})

答案 1 :(得分:2)

最后十一是:

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

或:

.{11}$

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

([0-9A-Fa-f]{2} ){11}

答案 2 :(得分:1)

1)^ [0-9A-F +] {8} [\ s] {2} [0-9A-F \ s] {34}(。*)

Parens用于分组提取。如何检索它取决于您的语言上下文,但现在在初始模式之后设置了一些$ 1。

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

(?:)是没有提取的分组。所以(?:[0-9A-F \ s]){11}将子模式视为一个单元,并重复查找它11次。

顺便说一句,我在这里假设PCRE。

答案 3 :(得分:0)

地址和ascii char都是十六进制的,所以:

^ [0-9A-F \ S] {42}

答案 4 :(得分:0)

匹配行尾是

.{11}$

要仅匹配结尾,您可以使用正面看法。

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

这将匹配任何字符,直到行尾,前提是它前面有“look behind”表达式。

(?&lt; = ....)定义了在匹配之前必须满足的条件。

我有点时间,但是如果你在网上看任何包含“regex”和“lookbehind”字样的教程,你会发现很好的东西(如果正则表达式教程涵盖前瞻/后方,它通常会非常完整和先进)。

另一个建议是获得正则表达式培训工具并使用它。看看这个优秀的Regex designer

答案 5 :(得分:0)

如果您使用的是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;

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