Perl:匹配额外字符串的正则表达式

时间:2012-09-24 17:40:04

标签: regex perl

我有以下字符串案例:

  • my $ str =“Warehouse.13.s01e01.hdtv.xor.avi”;
  • my $ str =“Warehouse.13.01x01.hdtv.xor.avi”;
  • my $ str =“Warehouse.13.season01episode01.hdtv.xor.avi”;

上述案例中的分隔符(.)可以替换为_ - \s。现在为了匹配上述情况,我创建了以下正则表达式,它工作正常:

my $regex_object = qr{.*?\d{1,2}(?:e|edosipe)?[._\- x]?\d{1,2}(?:s|nosaes)?[._\- ]?(?=\d+)(.*)};

你可以看到我必须反转字符串才能处理\d+,因为在后面应该有一个绝对长度匹配,所以我把它转换为预见。

现在对于上述情况,输出为Warehouse 13,这是我所需的输出。

现在的问题是如果我的series name不包含numbers(13,24)我不希望我的上述正则表达式匹配并确保我使用(?=\d+) i,e if { {1}}前面有数字。

现在,如果我的s|season$str,则它与上述正则表达式匹配并输出

'how.i.met.your.mother.s03e13.hdtv.mkv'

现在,即使在使用后视以及如何纠正它之后,我也不知道它为什么匹配这个字符串。

1 个答案:

答案 0 :(得分:2)

  

我不知道为什么它匹配这个字符串

.*?               "vkm.vtdh."
\d{1,2}           "31"
(?:e|edosipe)?    "e"
[._\- x]?         ""
\d{1,2}           "3"
(?:s|nosaes)?     ""
[._\- ]?          ""
(?=\d+)           "0"
(.*)              "0s.rehtom.ruoy.tem.i.woh"

可能的解决方案是改变(两者)

\d{1,2}

\d{1,2}(?!\d)  # Don't match just "3" of "30".
               # Bonus: Can't match part of "123".

(?>\d{1,2})    # Prevents it from matching just
               # one digit if there are two.
               # Note: Can match "12" of "123".

当然,(?=\d+)会导致整体失败。我不知道为什么它首先出现在那里。也许你的意思是(?!\d+)? (在这两种情况下,+都没用。)