1

Rubyを使用して正規表現を記述していますが、括弧の間に表示されるコロンを削除できる必要があります。使用できることを理解しています

"This is a (string :)".sub!(/\([^\)]*:/, '') 

これを行うには、問題は、この関数がコンテキストも一緒に削除することです。一致する式全体ではなく、コロンのみを削除するように指定する方法はありますか?

4

4 に答える 4

2

そのため、一部の正規表現エンジンは、文字と一致するが文字を消費しない、いわゆる先読みおよび後読みの一致をサポートします。Rubyは先読みをサポートしますが、後読みはサポートしません(これは、パフォーマンスの高い方法で行うのがより困難です)。つまりsub、閉じ括弧の前にあるコロンを非常に簡単に貼り付けて削除できますが、それが後にあることを確認する必要はありません。開き括弧:

string = 'This is a (string :)'
string.sub /:(?=\))/, ''
# => 'This is a (string )'

別の方法は、サブパターンキャプチャ(正規表現でグループ化を使用すると自動的に発生します)を使用して、望ましくない部分(この場合はコロン)なしで文字列を再構築することです。

string.sub /(\([^:]+):\)/, '\1)'

これ\1は、最初のグループで一致するものへの逆参照であり、エスケープされていない括弧で区切られています。ここでは、2番目のグループで閉じ括弧をわざわざキャプチャせず、代わりに単にそれを置換に含めることを選択したことがわかります。この場合、変更されないため、これはうまく機能しますが、括弧で囲まれたコンテンツの最後にコロンが表示されることがわからない場合は、2番目のグループが必要になります。

string.sub /(\([^:]+):([^)]+\))/, '\1\2'
于 2012-07-10T19:26:01.090 に答える
1

前の答えは、ほとんどの場合、親グループ内の単一のコロンを削除するために機能しますが、'(thing:foo:bar)`のような複数の問題があります。ルックビハインドとルックアヘッドを使用して、parens内のアサーションを作成するのは良いことですが、ruby(およびほとんどの正規表現エンジン)は、ルックビハインドで非決定論的な長さパターンをサポートしていません。

irb> s = 'x (a:b:c) : (1:2:3) y'
=> "x (a:b:c) : (1:2:3) y"

irb> s.gsub /(?<=\([^\(]*):(?=[^\)]*\))/, ''
SyntaxError: (irb):10: invalid pattern in look-behind: /(?<=\([^\(]*):(?=[^\)]*\))/
    from /Users/dbenhur/.rbenv/versions/1.9.2-wp/bin/irb:12:in `<main>'

代わりに、ブロック形式のgsubを使用して、親で囲まれたグループをキャプチャし、各一致からコロンを削除することができます。

irb> s.gsub(/\([^\)]*\)/) {|m| m.delete ':'}
=> "x (abc) : (123) y"
于 2012-07-10T22:04:21.197 に答える
0

一般的な正規表現では、次を使用できます'(\()(:)(\))', \1\3.

私はRubyに精通していません。基本的にあなたがしていることはあなたが3つのグループを持っているということです、そしてこの3つのグループから( : and )あなたは2番目のグループ、を取り除きます:

Notepad ++でテストしたところ、動作しました。

私はこれが呼ばれていると思います:正規表現の後方参照

乾杯。

于 2012-07-10T19:12:35.630 に答える
0

例のように、すべての括弧がバランスの取れたペアになると想定できる場合は、これで十分です。

"This is a (string :)".gsub!(/:(?=[^()]*\))/, '') 

先読みが最初に開始パレンを見ずに終了パレンを見つけることに成功した場合、コロンは(...)シーケンス内にある必要があります。開始パレンと終了パレンをどのように除外したかに注目してください。それは不可欠です。

于 2012-07-11T01:54:33.463 に答える