0

我想在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"

4

2 回答 2

4

使用.*?而不是.+?. 前者匹配零个或多个字符,而后者匹配一个或多个。

"Hello A=[] B=[boy] World".match(/A*=*\[(.*?)\]/)[1] # => ""
于 2013-07-09T08:45:43.353 回答
3

我会使用:

str = "Hello A=[apple] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => "apple"
str = "Hello A=[] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => ""

我不确定你为什么要使用A*=*,因为它的意思是“零个或多个'A'后跟零个或多个'='”并且基本上没有做任何有用的事情,事实上,实际上打开了一个返回的洞结果不好。请参阅下面编辑中的附加信息。

以下是相同主题的变体。所有都记录在正则表达式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 = "Hello A= [] B=[boy] World "

好吧,*=*这不是你应该做的。您需要告诉正则表达式引擎什么是可选的:

/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]. 这是因为您告诉它匹配 noA和 no=作为选项,这打开了要抓取的洞[foo]。只要您的输入恰好是两个选项,括号内没有前面的值,您就安全了。如果您有输入,您的结果将是错误的。


str[/A.*=.*\[(.*?)\]/,1]?

没有:

str = "Hello A=[apple] B=[boy] World"
str[/A.*=.*\[(.*?)\]/,1] # => "boy"

我建议探索如何通过Rubular使用正则表达式。这是显示上述示例及其失败原因的链接。

于 2013-07-09T08:52:35.437 回答