web-dev-qa-db-ja.com

連続した重複語の正規表現

私は正規表現の初心者であり、次のような重複する連続した単語に「一致する」単一の正規表現をどのように記述するかを理解することはできません。

パリ  春。

ない そのこと 関連しています。

なぜ笑っている?は 私の私の 悪いことですか??

上記のすべての太字文字列に一致する単一の正規表現はありますか?

98
Joshua

この正規表現を試してください:

\b(\w+)\s+\1\b

ここに \bは単語の境界であり、\1は、最初のグループのキャプチャされた一致を参照します。

118
Gumbo

私はこの正規表現がより多くの状況を処理すると信じています:

/(\b\S+\b)\s+\b\1\b/

テスト文字列の良い選択はここにあります: http://callumacrae.github.com/regex-tuesday/challenge1.html

19
Mike Viens

広く使用されているPCREライブラリは、このような状況を処理できます(ただし、POSIX準拠の正規表現エンジンではtheを達成できません)。

(\b\w+\b)\W+\1
5
soulmerge

以下のREでこれを試してください

  • \ b単語の単語の始まり
  • \ W +任意のWord文字
  • \ 1同じ単語が既に一致しています
  • \ b Wordの終わり
  • ()*もう一度繰り返す

    public static void main(String[] args) {
    
        String regex = "\\b(\\w+)(\\b\\W+\\b\\1\\b)*";//  "/* Write a RegEx matching repeated words here. */";
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE/* Insert the correct Pattern flag here.*/);
    
        Scanner in = new Scanner(System.in);
    
        int numSentences = Integer.parseInt(in.nextLine());
    
        while (numSentences-- > 0) {
            String input = in.nextLine();
    
            Matcher m = p.matcher(input);
    
            // Check for subsequences of input that match the compiled pattern
            while (m.find()) {
                input = input.replaceAll(m.group(0),m.group(1));
            }
    
            // Prints the modified sentence.
            System.out.println(input);
        }
    
        in.close();
    }
    
5
Faakhir

いいえ。それは不規則な文法です。使用できるエンジン/言語固有の正規表現があるかもしれませんが、それを行うことができる普遍的な正規表現はありません。

これは、複数の単語を複数回キャッチするものです。

(\b\w+\b)(\s+\1)+
3
synaptikon

Regex to Strip 2+ duplicate words(連続/非連続単語)

2つ以上の重複する単語をキャッチし、1つのWordのみを残すことができるこの正規表現を試してください。そして、重複する単語は連続する必要さえありません

/\b(\w+)\b(?=.*?\b\1\b)/ig

ここに、 \bはワード境界に使用され、?=は先読みに使用され、\1は、後方参照に使用されます。

ソース

2
Niket Pathak

これは、Twitchボットの重複フレーズを削除するために使用する正規表現です。

(\S+\s*)\1{2,}

(\S+\s*)は、空白ではなく、空白に続く文字列を探します。

\1{2,}は、一致する文字列でそのフレーズの3つ以上のインスタンスを探します。同一のフレーズが3つある場合、一致します。

2
Neceros

Javascriptの例:Good Partsは、これを行うために適合させることができます。

var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;

\ bはWord境界に\ wを使用します。\ wは[0-9A-Z_a-z]と同等です。その制限を気にしない場合、受け入れられる答えは結構です。

2
Daniel

この表現(上記のMikeに触発された)は、文字列の最後にあるものを含む、すべての重複、三重重複などをキャッチするようです。

/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")

duplicates onlyに一致するように求められた質問を知っていますが、triplicateは互いに2つの重複だけです:)

まず、(^|\s+)必ず完全なWordで始まるようにします。そうでない場合、「子のステーキ」は「子のステーキ」に移動します(「s」が一致します)。次に、すべての完全な単語((\b\S+\b))、文字列の終わり($)または複数のスペース(\s+)、全体が複数回繰り返されました。

私はこれを試してみましたが、うまくいきました:

var s = "here here here     here is ahi-ahi ahi-ahi ahi-ahi joe's joe's joe's joe's joe's the result result     result";
print( s.replace( /(\b\S+\b)(($|\s+)\1)+/g, "$1"))         
--> here is ahi-ahi joe's the result
1
Nico

一部の開発者は、重複する連続する非空白部分文字列だけでなく、3つ以上の重複文字列を排除するソリューションを求めてこのページに来ているので、適応パターンを示します。

パターン:/(\b\S+)(?:\s+\1\b)+/Pattern Demo
Replace:$1(キャプチャ文字列#1との完全な文字列の置換)

このパターンは、「空白全体」の非空白部分文字列に貪欲に一致し、1つ以上の空白文字(スペース、タブ、改行など)で区切られた一致部分文字列の1つ以上のコピーを必要とします。

具体的には:

  • \b(単語境界)文字は、単語の一部が一致しないようにするために不可欠です。
  • 2番目の括弧は非キャプチャグループです。これは、この可変幅の部分文字列をキャプチャする必要はなく、一致/吸収のみであるためです。
  • 非キャプチャグループの+(1つ以上の量指定子)は、*が正規表現エンジンを "bother"してシングルトンオカレンスをキャプチャおよび置換するため、*よりも適切です。無駄なパターン設計。

*文や句読点を含む入力文字列を扱う場合は、パターンをさらに改良する必要があります。

1
mickmackusa

重複する単語の大文字と小文字を区別しないチェックが必要な場合に使用します。

(?i)\\b(\\w+)\\s+\\1\\b
0
Neelam

次の式は、連続した単語をいくつでも見つけるために正しく機能するはずです。マッチングでは大文字と小文字が区別されない場合があります。

String regex = "\\b(\\w+)(\\s+\\1\\b)*";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

Matcher m = p.matcher(input);

// Check for subsequences of input that match the compiled pattern
while (m.find()) {
     input = input.replaceAll(m.group(0), m.group(1));
}

サンプル入力:さようならさよならGooDbYe

サンプル出力:さようなら

説明:

正規表現:

\ b:単語境界の始まり

\ w +:任意の数のWord文字

(\ s +\1\b)*:前のワードと一致し、ワード境界を終了するワードが続く任意の数のスペース。全体を*で囲むと、複数の繰り返しを見つけるのに役立ちます。

グループ化:

m.group(0):上記の場合に一致したグループを含むようにするGoodbye goodbye GooDbYe

m.group(1):上記の場合、一致したパターンの最初の単語を含むものとします

Replaceメソッドは、一致するすべての単語をWordの最初のインスタンスに置き換えます。

0
Aks789