我无法在Perl中匹配正则表达式,并且想知道是否有人有任何见解:
这是我的正则表达式:/^-MEMBER:\s+(\b[^,]+)(?:,\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/
这是我匹配的内容:
-MEMBER:Doe,John H ID#:3907
正则表达式工作得很漂亮并与上面的行匹配,但是对于任何可能不包含Firstname和Middle的行都有麻烦。示例如下:
-MEMBER:Doe,身份证号码:3907
我遇到了与当前正则表达式匹配的问题。
感谢您的帮助!
答案 0 :(得分:1)
您已将逗号匹配放在可选的名字组中,因此您只能在存在名字的情况下匹配逗号。如果逗号将伴随没有名字的姓氏,则需要将其移至姓氏组。
/^-MEMBER:\s+(\b[^,]+,)(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/
答案 1 :(得分:0)
这个正则表达式将匹配两行:
/
^-MEMBER:\s+ # the beginning of the line with "-MEMBER: "
.*? # non greedy
\s+ID#:\s+(\d+)$ # space and end ID part
/x
答案 2 :(得分: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
这很脆弱,因为它很难将假设编码到你的“语言”中。请注意,如果我们没有第一个/中间名,我们不允许使用逗号,因为它是 inside 可选组。这是你的第二次测试不匹配的问题。
其次,如果我们有第一个/中间名称部分,它可以包含除换行符之外的任何内容。这可能不是您想要或期望的。
解析器有用的原因并不一定是因为它们允许你拥有“上下文”,尽管他们这样做。这是因为它将复杂的正则表达式分解为小的,可管理的部分,这些部分连接在一起成为一个明确定义的整体。通过学习这样的工具,您在这里遇到的问题类型变得微不足道,并且更改。
请注意您的正则表达式如何尝试定义每个部分中的“有效”内容。姓氏(\b[^,]+)
除逗号外还可以包含任何内容!这是你想要的吗?如果有效名称中只有[a-zA-Z_]
,会发生什么? ;injectionattemptFTW!!;#
是有效名称吗?设计您的程序,以便有一组有限的,明显的条件。对于简单If a then valid, else fail
s,a
很容易推理。
除非您定义所有可能的特殊情况,否则您将遇到使此正则表达式中断的事情。我无法定义完美的正则表达式,因此您有两种选择:
如果您选择第一选项,则此正则表达式可以修复您当前的问题:
/^-MEMBER:\s+(\b[^,]+),?(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/