正则表达式,但忽略某些单词

时间:2013-06-19 16:01:54

标签: ruby regex

我正在成功使用正则表达式,但也许有点成功,我想添加一些例外,我不希望它影响某些词。 (参见我的previous question for some background ...这解决了给定的问题,现在我需要添加例外)。

因此,总而言之,我需要做的是:

  1. 找到类似[a-z]_[a-z]的模式,所以像some_var但不是_var这样的字词。
  2. 忽略在双引号内找到的匹配项,因此 "this_file.jpg"
  3. 忽略给定关键字列表中的匹配项,因此类似size_t等等(我有一系列例外情况)。
  4. 当我找到合适的匹配时,我将其转换为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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

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

注意:lookbehind(或前瞻)是一个只检查子模式但不消耗字符的断言。

另请注意,"[^"]"可以替换为"(?:[^"]+|(?<=\\)")+",以便在需要时允许双引号之间的双引号转义。

很好,ruby正则表达式引擎支持atomic groupspossessive quantifiers。你可以像这样重写你的表达以获得更多的表演:

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

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

答案 2 :(得分:1)

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

  1. 匹配候选词
  2. 拒绝禁止的keywrods
  3. 转换
  4. 我的经验也是,一旦你开始尝试进行更复杂的解析,你可能会看到比单纯形正则表达式更复杂的解析器。

答案 3 :(得分: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