2011-05-03 119 views
3

我一直在這一整天,我無法弄清楚。我在下面的一個字符串中有一些Ruby代碼,只想匹配其上的代碼和代碼的第一個註釋(如果存在的話)。尋找評論的Ruby正則表達式?

# Some ignored comment. 
1 + 1 # Simple math (this comment would be collected) # ignored 
# ignored 

user = User.new 
user.name = "Ryan" # Setting an attribute # Another ignored comment 

,這將捕捉:

    1. "1 + 1"
    2. "Simple math"
    1. "user = User.new"
    2. nil
    1. "user.name = "Ryan"
    2. "Setting an attribute"

我使用/^\x20*(.+)\x20*(#\x20*.+\x20*){1}$/來匹配每一行,但它似乎並沒有對所有的代碼工作。

+0

我不知道紅寶石,但我敢肯定'#簡單的數學(此評論將被收集)#ignored'是隻有一個評論,而不是兩個。第二個'#'被直接對待,因爲它已經被第一個'#'註釋掉了。 – BoltClock 2011-05-03 05:23:09

+0

我知道,這是我需要的功能。 – RyanScottLewis 2011-05-03 05:23:56

+1

這可能是非常難以不可能的。考慮像'user ='這樣的行,我們是#1 \「#_#」#comment',更不用說內聯註釋了(如果ruby有這些註釋,就像'i = 1 +/* comment */1')。你需要一些強大的,使用解析器(雖然這可能會忽略新行) – Kobi 2011-05-03 05:29:21

回答

2

而根本的問題是相當困難的,你可以找到你所需要的使用模式是什麼:

^[\t ]*[^\s#][^#\n\r]*#([^#\n\r]*) 

曰:

  • [\t ]* - 前導空格。
  • ​​- 一個實際的字符。這應該匹配代碼。
  • [^#\n\r]* - 直到#號的字符。除散列或換行符之外的任何內容。
  • #([^#\n\r]*) - 「第一」的評論,抓獲組1

工作例如:http://rubular.com/r/wNJTMDV9Bw

+0

適合我的男人,謝謝! – RyanScottLewis 2011-05-03 05:36:29

3

了Kobi的回答部分作品,但不匹配,缺乏在最後一個註釋行代碼。 str = "My name is #{first_name}

你需要一個更全面的正則表達式:

它還將在遇到串插,例如:

str = "My name is #{first_name} #{last_name}" # first comment 

失敗......會被錯誤地匹配。這裏有一個想法:

/^[\t ]*([^#"'\r\n]("(\\"|[^"])*"|'(\\'|[^'])*'|[^#\n\r])*)(#([^#\r\n]*))?/ 
  • ^[\t ]* - 領先的空白。
  • ([^#"'\r\n]("(\\"|[^"])*"|'(\\'|[^'])*'|[^#\n\r])*) - 匹配一行代碼。
    擊穿:
    • [^#"'\r\n] - 在一行代碼的第一個字符,並...
    • "(\\"|[^"])*" - 一個雙引號字符串,或...
    • '(\\'|[^'])*' - 單引號的字符串或...
    • [^#\n\r] - 引用字符串之外的任何其他字符,不是#或行結尾。
  • (#([^#\r\n]*))? - 匹配代碼行結尾處的第一條評論(如果有的話)。

由於更復雜的邏輯,這將爲每次比賽捕獲6個子模式。子模式1是代碼,子模式6是註釋,您可以忽略其他模式。

鑑於下面的代碼塊:

# Some ignored comment. 
1 + 1 # Simple math (this comment would be collected) # ignored 
# ignored 

user = User.new 
user.name = "Ryan #{last_name}" # Setting an attribute # Another ignored comment 

上述正則表達式將產生以下(I排除爲了簡潔子模式2,3,4,5):


  1. 1. 1 + 1
    6. Simple math (this comment would be collected)

  2. 1. user = User.new
    6.

  3. 1. user.name = "Ryan #{last_name}"
    6. Setting an attribute

演示:http://rubular.com/r/yKxEazjNPC