2

私は正規表現を正常に使用していますが、おそらく少し成功しすぎているため、いくつかの例外を追加したいと思います。特定の単語に影響を与えたくないのです。(背景については、以前の質問を参照してください...これにより、特定の問題が解決されました。例外を追加する必要があります)。

つまり、要約すると、私がする必要があるのは次のとおりです。

  1. [a-z]_[a-z]のようなパターンを見つけてsome_varください_var
  2. 二重引用符内にある一致は無視されるため "this_file.jpg" .
  3. キーワードの特定のリストでこれらの一致を無視するため、などではありませんsize_t(例外のリストがあります)。

適切な一致が見つかったら、それを基本的に ( 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たとえば) に一致しますが、禁止されたキーワードのリストをいつでも取得して、キャプチャされたグループが禁止された単語の 1 つに一致するかどうかを確認できます。そこからは仕事終わり。

正規表現のチュートリアル:

(?<!")          # 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

私はこれを次のようにします:

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 に答える
1

これをすべて1つの正規表現で実行する説得力のある理由があるかどうかを尋ねる必要がありますか? 重要であれば、ここでの複雑さは気にしません。しかし、より複雑な構文解析を行う必要があると思われる場合は、いくつかのステップに分割するだけの価値があるかもしれません。例えば、

  1. 候補の単語に一致
  2. 禁止されたキーワードを拒否する
  3. 変身

私の経験では、より洗練された解析を試み始めると、シンプレックス正規表現よりも洗練されたパーサーを検討するようになるかもしれません。

于 2013-06-19T16:24:24.600 に答える
1

後読みを使用し(?<=..)て、前に文字があり、保存された単語の長さが 2 を超えていることをテストできます。したがって、それらを交互に前に追加するだけです。

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

注:後読み(または先読み) は、サブパターンをチェックするだけで文字を消費しないアサーションです。

必要に応じて、二重引用符の間の二重引用符をエスケープ"[^"]"できるように置き換えることもできます。"(?:[^"]+|(?<=\\)")+"

Ruby の正規表現エンジンは、アトミック グループ所有量指定子をサポートしています。より多くのパフォーマンスのために、次のように式を書き換えることができます。

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

また

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