使用Ruby 2.4。我想通过说匹配任意数量的空格后跟一个出现在我的数组中的字母来创建一个正则表达式。所以我尝试了这个
Dim Active() As Variant
Dim i
ReDim Active(Range("G9:G24").Cells.Count)
For Each Zelle In Range("G9:G24")
If InStr(1, Zelle, "Active") <> 0 Then
Active(i) = Zelle.Offset(0, -4)
End If
i = i + 1
Next Zelle
For i = LBound(Active) To UBound(Active)
If Trim(Active(i)) <> "" Then
Debug.Print Active(i)
End If
Next i
End Sub
但正如您所看到的,尽管我的数组中的两个标记都没有结束,但两个标记都匹配。我如何重写我的正则表达式来解释这个问题?
答案 0 :(得分:2)
如果您对Regexen和插值不太谨慎,则会出现细微的错误。
你需要:
/[[:space:]]+(?:#{Regexp.union(LETTERS).source})$/i
以下是一个例子:
LETTERS = %w(a b).freeze
data = ['asdf f', 'sdfsdf x', 'test A', 'test a', 'testB', 'testb']
r = /[[:space:]]+(?:#{Regexp.union(LETTERS).source})$/i
# /[[:space:]]+(?:a|b)$/i
data.grep(r)
# ["test A", "test a"]
如果省略Regexp#source
:
r2 = /[[:space:]]+(?:#{Regexp.union(LETTERS)})$/i
# /[[:space:]]+(?:(?-mix:a|b))$/i
data.grep(r2)
# ["test a"]
请注意,Regexp.union
区分大小写。当它被导入较大的正则表达式时,它的标志也会被导入:(a|b)
区分大小写,因此它不匹配"test A"
。这是一个相关主题:Interpolating regexes into another regex
如果省略a|b
周围的parens:
r3 = /[[:space:]]+#{Regexp.union(LETTERS).source}$/i
# /[[:space:]]+a|b$/i
data.grep(r3)
# ["test A", "test a", "testB", "testb"]
空格只会在a
之前考虑。 "testB"
即使不应该匹配,也会匹配。
答案 1 :(得分:1)
<强>解决方案强>
Regexp.new("[[:space:]]+(#{Regexp.union(LETTERS).source})", Regexp::IGNORECASE)
您可以使用此正则表达式:
LETTERS = ["a","b"]
#=> ["a","b"]
regex = Regexp.new("[[:space:]]+#{Regexp.union(LETTERS)}", Regexp::IGNORECASE)
#=> /[[:space:]]+(?-mix:a|b)/i
data = ["asdf f", "sdfsdf x"]
#=> ["asdf f", "sdfsdf x"]
data.grep(regex)
#=> []
data = ["asdf f", "sdfsdf a"]
#=> ["asdf f", "sdfsdf a"]
data.grep(regex)
#=> ["sdfsdf a"]
但最内层的正则表达式不会忽略大小写。感谢@ EricDuminil的解决方案,很容易看出错误。