我想在A=[
和第一封]
之间得到任何内容:
> str = "Hello A=[apple] B=[boy] World"
> str.match(/A=\[(.+?)\]/)[1]
=> "apple"
到目前为止一切顺利。
然而,对于A=[]
:
> str = "Hello A=[] B=[boy] World"
> str.match(/A=\[(.+?)\]/)[1]
=> "] B=[boy"
如何获取空字符串""
,而不是"] B=[boy"
?
答案 0 :(得分:4)
使用.*?
而不是.+?
。前者匹配零个或多个字符,而后者匹配一个或多个字符。
"Hello A=[] B=[boy] World".match(/A*=*\[(.*?)\]/)[1] # => ""
答案 1 :(得分:3)
我会用:
str = "Hello A=[apple] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => "apple"
str = "Hello A=[] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => ""
我不确定你为什么使用A*=*
,因为它意味着“零或更多'A'后跟零或更多'='”并且基本上没有做任何有用的事情,事实上,实际上打开了一个洞,以返回不良结果。请参阅下面编辑中的其他信息。
以下是相同主题的变体。所有内容都记录在Regexp和String.[]
文档中:
str = "Hello A=[apple] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => "apple"
/A=\[(.*?)\]/ =~ str
$1 # => "apple"
str =~ /A=\[(.*?)\]/
$1 # => "apple"
/A=\[(?<in_brackets>.*?)\]/ =~ str
in_brackets # => "apple"
str = "Hello A=[] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => ""
/A=\[(.*?)\]/ =~ str
$1 # => ""
/A=\[(?<in_brackets>.*?)\]/ =~ str
in_brackets # => ""
= 旨在匹配等号之前或之后的可能空格字符,例如str =“你好A = [] B = [男孩]世界”
好吧,*=*
不是你应该怎么做的。你需要告诉正则表达式引擎什么是可选的:
/A *= */
是正确的,如:
/A ?= ?/
以下是一些测试,向您展示正在发生的事情:
str = "Hello [foo] A = [apple] B=[boy] World"
str[/A*=*\[(.*?)\]/, 1] # => "foo"
str[/A *=*\[(.*?)\]/, 1] # => nil
str[/A *= *\[(.*?)\]/, 1] # => "apple"
str[/A ?= ?\[(.*?)\]/, 1] # => "apple"
请注意,您的模式/A*=*/
允许引擎匹配[foo]
,而不是A = [apple]
。这是因为您告诉它不匹配任何A
和=
作为选项,这会打开抓住[foo]
的漏洞。只要您的输入正好是两个选项,在括号内没有前置值就可以安全。如果您有输入,那么结果将是错误的。
str[/A.*=.*\[(.*?)\]/,1]?
都能跟得上:
str = "Hello A=[apple] B=[boy] World"
str[/A.*=.*\[(.*?)\]/,1] # => "boy"
我建议您通过Rubular探索如何使用正则表达式。这是a link showing the above example以及它失败的原因。