我正在寻找正则表达式来捕获这些字符串示例:
first_paramenter, first_hash_key: 'class1 class2', second_hash_key: true
first_argument, single_hash_key: 'class1 class2'
first_argument_without_second_argument
模式规则是:
/^(\w+)/
true
,false
或由引号我正在使用这个正则表达式,但它只与第二个例子匹配:
^(\w+),(\s[a-z]{1}[a-z_]+:\s'?[\w\s]+'?,?)$
答案 0 :(得分:2)
我会选择以下内容:
^(\w+)(?:, ([a-z]\w+): ('[^']*')(?:, ([a-z]\w+): (\w+))?)?
(?:...)
创建非捕获组,我们可以使用?
轻松测试其存在。这样可以轻松测试可选块。
([a-z]\w+)
是一种简单的说法,它必须以字母“#34;同时允许正常的alpha,数字和" _"。
至于测试"值可以是true,false或用引号括起来的字符串",我会在捕获后在代码中执行此操作。创建复杂模式太容易了,以后无法维护它。使用简单的方法更好,然后看看你是否得到了你所期望的,而不是试图在正则表达式中强制执行它。
在第三个例子中,你的正则表达式返回5个匹配。如果只返回一个会更好。它有可能吗?
我不确定你在问什么。这将返回每个捕获的单个捕获,但是如果您要捕获要发送到方法的参数,那么为什么您对我没有任何意义:
/^(\w+(?:, [a-z]\w+: '[^']*'(?:, [a-z]\w+: \w+)?)?)/
答案 1 :(得分:1)
你有基本的想法,那里有一堆小错误
/^(\w+)(,\s[a-z][a-z_]+:\s('[^']*'|true|false))*$/
说明:
/^(\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
答案 2 :(得分:1)
在使用单个正则表达式攻击整个字符串或使用一个或多个String
方法破坏字符串之间经常可以选择,然后分别执行每个部分。后一种方法通常使调试和测试更容易,并且还可以使代码对于凡人来说是可理解的。当然,这总是一种判断,但我认为这个问题很适合分而治之的方法。我就是这样做的。
<强>代码强>
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