我有一些参数需要排序到不同的列表中。前缀确定它应属于哪个列表。
我使用类似:c
,a
,n
,o
和其他连字符(-
)的前缀来确定是否将其放入包含l它或排除列表。
我使用正则表达式分组为:
/^(-?)([o|a|c|n])(\w+)/
但是这里第三组(\w+
)不是通用的,它实际上应该依赖于第二组的结果。即,如果前缀是:
/\w{3}/
/\w{2}/
/\w+/
我可以用一个正则表达式执行此操作吗?目前我使用if
条件来执行此操作。
示例输入:
有效:
"-cABS", "-aXYZ", "-oWE", "-oqr", "-ncanbeanyting", "nstillanything", "a123", "-conT" (will go to c_exclude_list)
无效:
"cmorethan3chars", "c1", "-a1234", "prefizisnotvalid", "somethingelse", "oABC"
输出:对于每个arg推送到正确的列表,忽略无效。
c_include_list, c_exclude_list, a_include_list, a_exclude_list etc.
答案 0 :(得分:3)
您可以使用此模式:
/(-?)\b([aocn])((?:(?<=[ac])\w{3}|(?<=o)\w{2}|(?<=n)\w+))\b/
这个想法包括使用lookbehinds检查前一个字符而不将其包含在捕获组中。
答案 1 :(得分:1)
从版本2.0开始,Ruby已经从Oniguruma切换到Onigmo(Oniguruma的一个分支),这增加了对条件正则表达式以及其他功能的支持。
因此,您可以使用以下正则表达式根据前缀自定义模式:
^-(?:([ca])|(o)|(n))?(?(1)\w{3}|(?(2)\w{2}|(?(3)\w+)))$
答案 2 :(得分:0)
单一的,令人费解的正则表达式是处理这个问题的最佳方法吗?
这是一种更简单的方法,根本不使用正则表达式。我怀疑它至少与单个正则表达式一样有效,考虑到后者必须仍然将匹配的字符串分配给它们各自的数组。我认为它也更好看,更容易维护。如果我误解了问题的一些细节,下面的代码应该很容易修改。
<强>代码强>
def devide_em_up(str)
h = { a_exclude: [], a_include: [], c_exclude: [], c_include: [],
o_exclude: [], o_include: [], other_exclude: [], other_include: [] }
str.split.each do |s|
exclude = (s[0] == ?-)
s = s[1..-1] if exclude
first = s[0]
s = s[1..-1] if 'cao'.include?(first)
len = s.size
case first
when 'a'
(exclude ? h[:a_exclude] : h[:a_include]) << s if len == 3
when 'c'
(exclude ? h[:c_exclude] : h[:c_include]) << s if len == 3
when 'o'
(exclude ? h[:o_exclude] : h[:o_include]) << s if len == 2
else
(exclude ? h[:other_exclude] : h[:other_include]) << s
end
end
h
end
示例强>
让我们试一试:
str = "-cABS cABT -cDEF -aXYZ -oWE -oQR oQT -ncanbeany nstillany a123 " +
"-conT cmorethan3chars c1 -a1234 prefizisnotvalid somethingelse oABC"
devide_em_up(str)
#=> {:a_exclude=>["XYZ"], :a_include=>["123"],
# :c_exclude=>["ABS", "DEF"], :c_include=>["ABT"],
# :o_exclude=>["WE", "QR"], :o_include=>["QT"],
# :other_exclude=>["ncanbeany"], :other_include=>["nstillany"]}