2017-04-16 44 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] *'代替。 –