arrays - 如何在另一个字符串的开头匹配数组中的字符串

标签 arrays ruby regex string

我想不区分大小写地匹配我的数组 TOKENS 中的一个字符串,它位于另一个字符串的开头,后跟一个空格或行尾。

我的 token 数组如下所示:

2.4.0 :013 > TOKENS = ["m", "o"]
 => ["m", "o"]

当我尝试匹配数组中的每个元素时,它选出了错误的结果:

2.4.0 :009 > data_col = ["M", "b", "Mabc", "abc m b"]
 => ["M", "b", "Mabc", "abc m b"]
...
2.4.0 :015 > data_col.select{|string| string =~ /^[#{Regexp.union(TOKENS)}]([[:space:]]|$)/i }
 => ["M", "b"]

这与“M”和“b”条目都匹配,即使“b”没有出现在我的 token 列表中。如何修改我的正则表达式以便只匹配正确的值“M”?

我正在使用 Ruby 2.4。

最佳答案

我会使用:

TOKENS = ["m", "o"]
DATA_COL = ["M", "b", "Mabc", "abc m b"]
RE = /^(?:#{Regexp.union(TOKENS).source})(?: |$)/i

DATA_COL.select{ |string| string[RE] }
# => ["M"]

分解一下:

Regexp.union(TOKENS).source # => "m|o"
/^(?:#{Regexp.union(TOKENS).source})(?: |$)/i # => /^(?:m|o)(?: |$)/i

/^[#{Regexp.union(TOKENS)}]([[:space:]]|$)/i 在循环中不是一个好主意。每次通过你强制 Ruby 创建模式;效率在循环内部很重要,尤其是大循环,因此在循环外部创建模式然后引用内部模式。

下一个问题是 Regexp.union 有一个它应该匹配的正确大小写的概念:

Regexp.union(TOKENS).to_s        # => "(?-mix:m|o)"

(?-mix: 部分是正则表达式引擎如何记住模式的标志。当模式嵌入到另一个模式中时,他们继续知道他们应该寻找什么,导致我们咬牙切齿流泪:

/#{Regexp.union(TOKENS)}/i # => /(?-mix:m|o)/i

尾随的 i 告诉模式它应该忽略大小写,但是嵌入的 i 没有设置所以它是尊重大小写。这就是打破你的模式的原因。

修复方法是像我上面那样在嵌入时使用 source

有关更多信息,请参阅正则表达式“options”部分。

关于arrays - 如何在另一个字符串的开头匹配数组中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44296269/

相关文章:

ruby-on-rails - Rails- Controller :notice - Add a variable?

.net - 正则表达式挑选艺术家姓名和歌曲标题,存在惰性匹配问题

正则表达式在斜杠之间查找字符串

arrays - 将值插入数组时 VBA 函数失败

c - 如何读取带有空格的输入并将输入排序到 2 个数组?

ios - 从日期范围创建日期字符串数组

php - 有很多值的数组

ruby-on-rails - 检查 ActiveRecord 查找是否返回结果

ruby - 使用 Jekyll/Liquid 将 Markdown 内容传递给 Ruby 函数

javascript - 什么是删除大写字母之间的空格但保留单词之间的空格的正则表达式?