Ruby 正则表达式,但忽略某些单词
我成功地使用了正则表达式,但可能有点太成功了,我想给它添加一些例外,一些我不希望它影响的词。(参见我的…,这解决了给定的问题,现在我需要添加例外) 总之,我需要做的是:Ruby 正则表达式,但忽略某些单词,ruby,regex,Ruby,Regex,我成功地使用了正则表达式,但可能有点太成功了,我想给它添加一些例外,一些我不希望它影响的词。(参见我的…,这解决了给定的问题,现在我需要添加例外) 总之,我需要做的是: 找到一个像[a-z]\uu[a-z]这样的模式,这样像这样的词就有一些变量,而不是\u变量 忽略在双引号中找到的匹配项,因此不“this_file.jpg” 忽略给定关键字列表中的匹配项,因此不是size\u t等(我有一个例外列表) 当我找到一个合适的匹配项时,我将其转换为camelCase,本质上是(someVar->som
[a-z]\uu[a-z]
这样的模式,这样像这样的词就有一些变量
,而不是\u变量
“this_file.jpg”
size\u t
等(我有一个例外列表)someVar
->someVar
),这在前面的问题中得到了成功的回答
这是用Ruby编写的,到目前为止,我的代码是这样的:
exclusions = ["size_t", "other_t"]
replacement = text.gsub(/"[^"]+"|_[a-z]/) {|match| (match.length > 2)? match : match[1].upcase } # doesn't do any exclusions from my list, only handles the quoted case.
我有点不知所措。我想我需要一些消极的前瞻,但我不确定如何做到这一点(对正则表达式没有太多的经验)
样本
输入:
this_var "that_var" size_t
输出:
thisVar "that_var" size_t
thisVar "that_var" size_t
也就是说,引号中的内容应该保持不变,我的排除列表中的内容也应该保持不变。任何与
[a-z].[a-z]
匹配的其他字符串都应该更改。您可以使用lookback(?我不知道ruby,但我可以在这里给出一个算法
可以按如下方式实现不带引号的匹配单词(注意:literal regex;在Ruby中做任何必要的事情使其成为可读的regex):
我必须问一下,是否有令人信服的理由在一个正则表达式中完成这一切?如果它很重要,我并不介意这里的复杂性。但如果您认为您将不得不进行更复杂的解析,那么将其分解为几个步骤可能是值得的。例如
匹配候选词
拒绝禁止的密钥
转化
我的经验是,一旦开始尝试进行更复杂的解析,您可能会研究比simplex regex更复杂的解析器。我会这样做:
input.gsub /"?[a-z]+_[a-z]+"?/ do |match|
if match[0] == '"' && match[-1] == '"' || blacklist.include?(match)
match
else
match.gsub(/_[a-z]/) { |match| match[1].upcase }
end
end
黑名单
是您不希望替换的单词数组
测试:
输出:
thisVar "that_var" size_t
thisVar "that_var" size_t
如果您准确地包含示例输入和输出,这将非常有帮助。您可能希望为此使用至少两个单独的正则表达式,尤其是对于包含单词列表的部分。基于排除列表排除数据的非常粗糙的方法是%r{exclusions.join(“|”)}
它将生成正则表达式/size\u t | other\u t/
。
(?<!") # position where the preceding text is not a double quote
( # start group
[a-z]+ # one character among 'a' - 'z', one or more times, followed by
(?: # begin non capturing group
_ # an underscore, followed by
[a-z]+ # one character among 'a' - 'z', one or more times
) # end non capturing group
* # zero or more times, followed by
(?!") # a position where what immediately follows is not a double quote
input.gsub /"?[a-z]+_[a-z]+"?/ do |match|
if match[0] == '"' && match[-1] == '"' || blacklist.include?(match)
match
else
match.gsub(/_[a-z]/) { |match| match[1].upcase }
end
end
input = 'this_var "that_var" size_t'
blacklist = %w{size_t other_t}
output = input.gsub /"?[a-z]+_[a-z]+"?/ do |match|
if match[0] == '"' && match[-1] == '"' || blacklist.include?(match)
match
else
match.gsub(/_[a-z]/) { |match| match[1].upcase }
end
end
puts output
thisVar "that_var" size_t