9

で区切られた識別子の文字列が与えられた場合:、正規表現を構築して一意の識別子を別の文字列に抽出し、これも ? で区切られ:ますか?

正規表現を使用してこれを達成するにはどうすればよいですか? は貪欲で の最後のマッチにスキップするs/(:[^:])(.*)\1/$1$2/gため、うまくいきませんでした。(.*)$1

例:a:b:c:d:c:c:x:c:c:e:e:f与えるべきa:b:c:d:x:e:f

注: 私は perl でコーディングしていますが、正規表現を使用していただければ幸いです。

4

5 に答える 5

10

後読み内での無限の繰り返しをサポートする .NET では、次を検索できます。

(?<=\b\1:.*)\b(\w+):?

すべての一致を空の文字列に置き換えます。

Perl (少なくとも Perl 5) は固定長の後読みのみをサポートしているため、次のことを試すことができます (先読みを使用すると、微妙に異なる結果が得られます)。

\b(\w+):(?=.*\b\1:?)

これを空の文字列に置き換えると、重複エントリの以前の繰り返しがすべて削除されます。最後のものは残ります。だから代わりに

a:b:c:d:x:e:f

あなたが得るだろう

a:b:d:x:c:e:f

それがOKなら、あなたは使うことができます

$subject =~ s/\b(\w+):(?=.*\b\1:?)//g;

説明:

最初の正規表現:

(?<=\b\1:.*): 後方参照番号の内容が一致するかどうかを確認します。1 の後に、文字列の前のどこかでコロンが続きます。

\b(\w+):?: 識別子 (単語境界から次の まで:) に一致し、オプションでコロンが続きます。

2 番目の正規表現:

\b(\w+):: 識別子とコロンを一致させます。

(?=.*\b\1:?): 次に、文字列の前方のどこかで、オプションでコロンが続く同じ識別子に一致するかどうかを確認します。

于 2010-07-22T14:43:00.367 に答える
2

チェックアウト: http://www.regular-expressions.info/duplicatelines.html

正規表現について考えるときは常に役立つサイトです。

于 2010-07-22T14:18:05.730 に答える
1
$str = q!a:b:c:d:c:c:x:c:c:e:e:f!;

1 while($str =~ s/(:[^:]+)(.*?)\1/$1$2/g);

say $str

出力:

a:b:c:d:x:e:f
于 2010-07-22T14:42:14.660 に答える
0

識別子がソートされている場合は、lookahead/lookbehindを使用してソートできる場合があります。そうでない場合、これは正規表現の計算能力を超えています。さて、正式な正規表現では不可能だからといって、perl固有の正規表現機能を使用しても不可能というわけではありませんが、正規表現を移植可能に保ちたい場合は、変数をサポートする言語でこの文字列を記述する必要があります。

于 2010-07-22T14:37:23.440 に答える
0

これは awk バージョンです。正規表現は必要ありません。

$ echo "a:b:c:d:c:c:x:c:c:e:e:f" | awk -F":" '{for(i=1;i<=NF;i++)if($i in a){continue}else{a[$i];printf $i}}'
abcdxef

「:」でフィールドを分割し、分割されたフィールドを通過し、要素を配列に格納します。存在を確認し、存在する場合はスキップします。それ以外の場合は、それらを印刷します。これを簡単に Perl コードに変換できます。

于 2010-07-22T14:44:49.553 に答える