我试图从以下形式的字符串中提取子字符串:
dest=comp;jump
我正在寻找正则表达式来检索comp
,但dest
和jump
都是可选的,在这种情况下,=
或;
被省略。所以这些都是有效的配置:
dest=comp;jump
dest=comp
comp;jump
comp
dest
,comp
和jump
是任意字符串,但不包含等号或分号。
我设法提出的是以下内容:
(?:=)([^;=]*)(?:;)
不幸的是,当省略dest
或jump
时,它不起作用。
答案 0 :(得分:2)
怎么样:
(?:.*=|^)([^;]+)(?:;|$)
您要搜索的字符串位于第1组。
答案 1 :(得分:0)
如果整行必须有这种形式,那么应该这样做:
if line.chomp =~ /\A(?:[^;=]+=)?([^=;]+)(?:;[^;=]+)?\z/
puts $1
end
这会跳过像
这样的格式错误的行"dest=dest=comp;jump;jump"
答案 2 :(得分:0)
我不会试图让一切都发生在一个正则表达式中。这条路使得阅读和维护更加困难。相反,我会使用case
/ when
语句将其分解为更多原子测试:
如果你只想要comp
,我会使用:
array = %w[
dest=comp;jump
dest=comp
comp;jump
comp
].map{ |str|
case str
when /.+=(.+);/, /=(.+)/, /(.+);/
$1
else
str
end
}
array
# => ["comp", "comp", "comp", "comp"]
when
子句将复杂性分解为三个小测试,每个测试都很容易理解:
'='
和';'
?然后返回这两个字符之间的子字符串。'='
?然后返回最后一个字。';'
?然后返回第一个单词。如果您需要知道正在返回哪些条款,则需要更多代码:
%w[
dest=comp;jump
dest=comp
comp;jump
comp
].each{ |str|
dest, comp, jump = case str
when /(.+)=(.+);(.+)/
[$1, $2, $3]
when /(.+)=(.+)/
[$1, $2, nil]
when /(.+);(.+)/
[nil, $1, $2]
else
[nil, str, nil]
end
puts 'dest="%s" comp="%s" jump="%s"' % [dest, comp, jump]
}
# >> dest="dest" comp="comp" jump="jump"
# >> dest="dest" comp="comp" jump=""
# >> dest="" comp="comp" jump="jump"
# >> dest="" comp="comp" jump=""
答案 3 :(得分:0)
我只是尝试将表达式分成两部分,以便更容易理解发生的事情:
string = 'dest=comp;jump'
trimming_regexp = [/.*=/, /;.*/]
trimming_regexp.each{|exp| string.slice!(exp)}