2014-07-25 40 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

您需要提供预期输出的示例以及您打算如何使用它们。将它们添加到您的问题。就个人而言,我不会试图在模式中这样做。一旦你得到了捕捉,很容易将其他形式的东西按摩。 –