2

我成功地使用了一个正则表达式,但可能有点成功了,我想给它添加一些例外,我不希望它影响某些词。(有关一些背景信息,请参阅我之前的问题......这解决了给定的问题,现在我需要添加例外)。

所以,总而言之,我需要做的是:

  1. 找到一个模式like [a-z]_[a-z],这样的话like some_varbut not _var
  2. 忽略在双引号内找到的那些匹配项,所以不是 "this_file.jpg".
  3. 忽略给定关键字列表中的那些匹配项,所以不要size_t, 等(我有一个例外列表)。

当我找到合适的匹配时,我将其转换为 camelCase,本质上是 ( some_var-> 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

也就是说,引号中的东西应该保持不变,我的排除列表中的东西也应该保持不变。[a-z]_[a-z]应更改任何其他匹配的字符串。

4

4 回答 4

2

我不知道红宝石,但我可以在这里给出一个算法。

可以按如下方式匹配不带引号的单词(注意:文字正则表达式;在 Ruby 中做任何必要的事情以使其成为可读的正则表达式):

(?<!")([a-z]+(?:_[a-z]+)*)(?!")

这将匹配禁止关键字(size_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
于 2013-06-19T16:08:55.963 回答
1

您可以使用lookbehind(?<=..)来测试您之前是否有一个字母,并且保留的单词的长度大于2,因此只需在交替中添加它们。

text.gsub(/"[^"]+"|size_t|(?<=[a-z])_[a-z]/) {|match| (match.length > 2)? match : match[1].upcase }

注意:lookbehind(或lookahead)是一个仅检查子模式但不使用字符的断言。

还要注意,如果需要,"[^"]"可以将其替换"(?:[^"]+|(?<=\\)")+"为允许双引号之间的转义双引号。

总之,ruby 正则表达式引擎支持原子组所有格量词。您可以像这样重写您的表达式以获得更多性能:

/"[^"]++"|size_t|(?<=[a-z])_[a-z]/

或者

/"(?>[^"]++|(?<=\\)")+"|size_t|(?<=[a-z])_[a-z]/
于 2013-06-19T16:06:40.923 回答
1

我不得不问是否有令人信服的理由在一个正则表达式中完成这一切?如果它很重要,我不介意这里的复杂性。但是,如果您认为您将不得不进行更复杂的解析,那么将其分解为几个步骤可能是值得的。例如,

  1. 匹配候选词
  2. 拒绝禁止的关键字
  3. 转换

我的经验也是,一旦您开始尝试进行更复杂的解析,您可能会研究比单纯正则表达式更复杂的解析器。

于 2013-06-19T16:24:24.600 回答
1

我会这样做:

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

blacklist是您不想替换的单词数组。

测试:

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
于 2013-06-19T16:28:24.757 回答