2014-07-25 43 views
-1

我尋找一個正則表達式捕捉到的字符串這樣的例子:正則表達式來捕獲串入紅寶石方法PARAMS

first_paramenter, first_hash_key: 'class1 class2', second_hash_key: true 
first_argument, single_hash_key: 'class1 class2' 
first_argument_without_second_argument 

模式的規則是:

  • 字符串必須啓動一些字(第一參數)/^(\w+)/
  • 第二個參數是可選的
  • 如果提供了第二個參數,則必須在fisrt參數
  • 之後有一個逗號
  • 第二個參數是一個散列,包含鍵和值。值可以是truefalse或加引號的字符串
  • 混雜鍵必須以字母

我使用這個正則表達式的開始,但它唯一的第二個例子匹配:

^(\w+),(\s[a-z]{1}[a-z_]+:\s'?[\w\s]+'?,?)$ 
+0

問題將受益於幾個例子。 –

回答

1

經常有一種選擇要用一個正則表達式攻擊整個字符串或用一個或多個方法斷開字符串,然後分別追蹤每個片段。後一種方法通常使得調試和測試更容易,並且還可以使代碼易於人類理解。當然,這總是一個判斷的呼聲,但我認爲這個問題很適合分而治之的方法。我就是這麼做的。

代碼

def match?(str) 
    a = str.split(',') 
    return false unless a.shift.strip =~ /^\w+$/ 
    a.each do |s| 
    return false unless ((key_val = s.split(':')).size == 2) && 
          key_val.first.strip =~ /^[a-z]\w*$/ && 
          key_val.last.strip =~ /^(\'.*?\'|true|false)$/ 
    end 
    true 
end 

例子

match?("first_paramenter, first_hash_key: 'class1 class2', 
          second_hash_key: true") 
    #=>true 
match?("first_argument, single_hash_key: 'class1 class2'") 
    #=>true 
match?("first_argument_without_second_argument") 
    #=>true 
match?("first_parameter, first_hash_key: 7") 
    #=>false 
match?("dogs and cats, first_hash_key: 'class1 class2'") 
    #=>false 
match?("first_paramenter, first_hash_key: 'class1 class2', 
          second_hash_key: :true") 
    #=>false 
1

你已經有了基本的想法,你有一堆小錯誤在那裏

/^(\w+)(,\s[a-z][a-z_]+:\s('[^']*'|true|false))*$/ 

解釋說:

^(\w+)(?:, ([a-z]\w+): ('[^']*')(?:, ([a-z]\w+): (\w+))?)? 

Here's a Rubular example

/^(\w+)    # starts with a word 
    (
    ,\s    # the comma goes _inside_ the parens since its optional 
    [a-z][a-z_]+:\s # {1} is completely redundant 
    (    # use | in a capture group to allow different possible keys 
     '[^']*' |  # note that '? doesn't make sure that the quotes always match 
     true | 
     false 
    ) 
)*$/x    # can have 0 or more hash keys after the first word 
+0

Max,你的正則表達式不會返回正確的匹配:http://rubular.com/r/Ko1UnqTtzs – Rodrigo

2

我喜歡的東西去。

(?:...)創建非捕獲組,我們可以使用?輕鬆測試存在。這樣可以很容易地測試可選塊。

([a-z]\w+)是一個簡單的方法來說「它必須以字母開頭」,同時允許正常的字母,數字和「_」。

至於測試「值可以是真,假或用引號括起來的字符串」,我會在捕獲後在代碼中執行此操作。創建複雜模式非常容易,之後無法維護。最好使用簡單的,然後看看你是否得到你所期望的,而不是嘗試在正則表達式中強制執行它。


在第三個例子

,您正則表達式返回5場比賽。如果只返回一個會更好。這是可能的?

我不確定你在問什麼。這將返回單個捕獲每一個,但是爲什麼你要的是沒有意義的我,如果你拍攝參數發送給一個方法:

/^(\w+(?:, [a-z]\w+: '[^']*'(?:, [a-z]\w+: \w+)?)?)/ 

http://rubular.com/r/GLVuSOieI6

+0

不錯!但在第三個例子中,你的正則表達式會返回5個匹配項。如果只返回一個會更好。這是可能的? – Rodrigo

+0

您需要提供預期輸出的示例以及您打算如何使用它們。將它們添加到您的問題。就個人而言,我不會試圖在模式中這樣做。一旦你得到了捕捉,很容易將其他形式的東西按摩。 –