2013-03-14 57 views
1
我有匹配Perl中的正则表达式的麻烦

匹配,并想知道如果任何人有任何见解:麻烦与正则表达式在Perl

这里是我的正则表达式:/^-MEMBER:\s+(\b[^,]+)(?:,\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/

这里是我的匹配:

-Member:DOE,约翰•H•编号:3907

正则表达式的作品精美,上面的线相匹配,但我有特鲁与任何可能不包含名字和中间名的行相混淆。下面的实施例:

-Member:DOE,编号:3907

我有与当前正则表达式匹配的麻烦,这两条线。

感谢您的帮助!

回答

0

此正则表达式匹配两条线:

/ 
    ^-MEMBER:\s+   # the beginning of the line with "-MEMBER: " 
    .*?     # non greedy 
    \s+ID#:\s+(\d+)$  # space and end ID part 
/x 
+0

非常感谢你Sputnick,解决了我的问题! – flipout 2013-03-14 17:57:07

1

你已经把你的逗号匹配您的选购姓组里面,所以你只能在一个名字存在匹配一个逗号。如果逗号将伴随没有名字的姓氏,您需要将其移至姓氏组。

/^-MEMBER:\s+(\b[^,]+,)(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/ 
0

问题是,你到底是什么语法描述你的输入。试图一口气描述这一切变得非常复杂,非常快速。有关替代方法,请参阅perl yapp module

但是,如果你在仅仅使用正则表达式坚持,在这里我们去:

/^-MEMBER: # start of line, match specific string 
\s+ # must be followed by at least one whitespace char 
(\b[^,]+) # now we need to match a word in a capture group 
(?:,\s(\b.{1,50}\b)\.?)? # here's the pain, so lets deal with it below 
\s+ # more whitespace 
ID#: # match this string 
\s+ # and some more whitespace 
(\d+)$/ # digits at the end of the line 

(
?: # cluster the following 
,\s # comma, then a single space 
(
    \b.{1,50}\b # up to fifty "things" bounded by words 
) # another capture group 
\.? # optional period 
)? # zero or one of these I.E. optional capture 

这是防撞的,因为它硬编码的假设到你的“语言”。请注意,如果我们没有第一个/中间名,我们不允许逗号,因为它是里面的可选组。这是你的第二个测试不匹配的问题。其次,如果我们有第一个/中间名称部分,它可以包含除换行符以外的任何内容。这可能不是你想要或期望的。

解析器很有用的原因不一定是因为它们允许您拥有“上下文”,尽管他们这样做。这是因为它将你复杂的正则表达式分解成小的,易于管理的片断,连接成一个明确定义的整体。通过学习这样的工具,您在这里遇到的问题类型变得微不足道,并且更改为

注意你的正则表达式是如何试图在每一节中定义什么是“有效”的。姓氏(\b[^,]+)除逗号之外可以有其他任何内容!这是你想要的吗?如果有效名称只能包含[a-zA-Z_],会发生什么情况? ;injectionattemptFTW!!;#是一个有效的名字吗?设计你的程序,以便有一个有限的,明显的条件。 If a then valid, else fail很容易推理简单a s。

除非你定义了所有可能的特殊情况,否则你会遇到使正则表达式中断的事情。我不能定义一个完美的正则表达式,所以你有两个选择:

  1. 补丁正则表达式,为更复杂的特殊情况确定
  2. 重新设计,以避免复杂的正则表达式

如果您需要选择一个选项,然后这个正则表达式修复你当前的问题:

/^-MEMBER:\s+(\b[^,]+),?(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/