2017-04-16 43 views
0

这里是我匹配红宝石用正则表达式匹配可选

AQUEDUCT - March 25, 2017 - Race 4\n MAIDEN CLAIMING - Thoroughbred\n 
INNER DIRT FOR MAIDENS, FOUR YEARS OLD AND UPWARD FOALED IN NEW YORK STATE AND 
APPROVED BY THE\n NEW YORK STATE-BRED REGISTRY. Weight, 121 lbs. Claiming 
Price $25,000. (S) Claiming Price: $25,000\n Six Furlongs On The Inner track 
Track Record: (Captain Red - 1:07.93 - February 26, 2003)\n Purse: 

此正则表达式失败的文本,即使可选claiming_price条款是由非贪婪之前“ *?”序列。

/(Thoroughbred).*?(?<claiming_price>Claiming Price:.*?\n)?.*Track Record:/m 

当我取出“?”在claiming_price子句之后,它起作用

/(Thoroughbred).*?(?<claiming_price>Claiming Price:.*?\n).*Track Record:/m 

为什么当claiming_price子句是可选匹配时它不工作?如何获得匹配并保持claiming_price子句可选?

编辑:我将如何使这个更复杂的正则表达式的工作?这是我正在与之合作的人。我简化了原文,让读者更容易。但我正在处理您的答案,我不知道如何将其应用于我的真正正则表达式。

/(Thoroughbred|Quarter Horse)\n(?<rules>.*?)(?<claiming_price>Claiming Price:.*?\n)?(?<track_type>(?:(?!\n).)*?)Track Record:.*? - (?<track_record>\d.*?\d) -.*\nPurse/m 
+0

“失败”和“作品”是什么意思?除非存在Ruby错误,否则正则表达式可以工作。 – sawa

回答

2

不要在声称价格捕获组使用?量词(即保持它的强制性,恰好一次匹配),并与.*?一起包起来才可选的非捕获内组:

/(Thoroughbred)(?:.*?(?<claiming_price>Claiming Price:.*?\n))?.*Track Record:/m 
       ^^           ^^ 

Rubular demo

现在,它的工作是这样的:

  • (Thoroughbred) - Thoroughbred
  • (?:.*?(?<claiming_price>Claiming Price:.*?\n))? - 一个或零(?)发生:
    • .*? - 任何0+字符尽可能少到随后的子模式的第一次出现
    • (?<claiming_price>Claiming Price:.*?\n) - claiming_price集团捕获
      • Claiming Price: - Claiming Price:
      • .*?\n - 任何0+字符尽可能少,直到第一个换行符
  • .* - 任何0+字符尽可能多的高达最后一次出现
  • Track Record: - Track Record: string。

为什么它不适用于你的第一个正则表达式?

(Thoroughbred)匹配Thoroughbred。然后,.*?模式,被懒惰地量化,首先被跳过,并(?<claiming_price>Claiming Price:.*?\n)?被尝试。由于Claiming Price:Thoroughbred之后不存在,因此用?量化的模式匹配空字符串(因为?量词可以匹配1或0个这样的模式序列)。然后,.*Track Record:抓住了比赛的其余部分(任何0+字符到最后一次出现Track Record:)。

+0

谢谢你的回答。这是非常有帮助的。我编辑我的OP,如果我可以进一步麻烦你。我正在研究你的帖子,但我不知道如何将你的观点应用于我真实的,更复杂的正则表达式。 – appleLover

+1

@appleLover:同样的技术 - 将'。*?'和下一个组合包装成一个可选的非捕获组 - 参见[这个演示](http://rubular.com/r/hsjca8XFhP)。另外,当用单个字符限制一个'.'时,'(?:(?!\ n)。)*'锻炼贪婪标记是没有意义的,用'[^ ​​\ n] *'代替。 –