5

telnet クライアントからの文字列があります。この文字列には、適用する必要があるバックスペース文字が含まれています。各バックスペースは、以前に入力した 1 文字を削除する必要があります。

正規表現を使用して単一の置換でこれを実行しようとしています:

string txt = "Hello7\b World123\b\b\b";
txt = Regex.Replace(txt, ".\\\b", "", RegexOptions.ECMAScript);

その結果、「Hello World12」になります。もちろん、「12」も外してほしいのですが、明らかに私の表現と一致しません。

何らかの方法で、一致がなくなるまで置換を繰り返す必要があります。単一の正規表現でこれを達成する方法についてのアイデアはありますか?

4

2 に答える 2

4

私はこれに正規表現を使用しようとはしません。なぜなら、それは読むのが非常に難解であり、perl のような正規表現の魔法の拡張機能がなければ、単純な正規表現では不可能であると感じているからです。私の提案は次のようなものです(pythonのような擬似コード):

stack = []
for char in str:
    if char == BACKSPACE and not stack.isEmpty():
        stack.pop()
    else:
        stack.push(char)

result = ''.join(stack)

何が起こり、どのように機能するかはすぐにわかります。

于 2013-05-17T08:30:58.037 に答える
4

これは基本的にHow can we match a^nb^n with Java regex?の変形です。、そこでその答えを再利用できます:

var regex = new Regex(@"(?:[^\b](?=[^\b]*((?>\1?)[\b])))+\1");
Console.WriteLine(regex.Replace("Hello7\b World123\b\b\b", ""));

さらに、.NET 正規表現エンジンはバランシング グループをサポートしているため、別のパターンを使用できます。

var regex = new Regex(@"(?<L>[^\b])+(?<R-L>[\b])+(?(L)(?!))");

(これの意味は:

  1. 1 つまたは複数の非バックスペースに一致し、それらに「L」という名前を割り当てます。
  2. 次に、1 つまたは複数のバックスペースを続けて、"R" という名前を割り当て、すべての "R" に対応する "L" が 1 つ必要であるという条件付きで、
  3. 「L」が残っている場合は、一致を破棄します ((?!)何も一致しないため)。

)

于 2013-05-17T08:31:56.577 に答える