私は正規表現の初心者であり、次のような重複する連続した単語に「一致する」単一の正規表現をどのように記述するかを理解することはできません。
パリ の 春。
ない そのこと 関連しています。
なぜ笑っている?は 私の私の 悪いことですか??
上記のすべての太字文字列に一致する単一の正規表現はありますか?
この正規表現を試してください:
\b(\w+)\s+\1\b
ここに \b
は単語の境界であり、\1
は、最初のグループのキャプチャされた一致を参照します。
私はこの正規表現がより多くの状況を処理すると信じています:
/(\b\S+\b)\s+\b\1\b/
テスト文字列の良い選択はここにあります: http://callumacrae.github.com/regex-tuesday/challenge1.html
広く使用されているPCREライブラリは、このような状況を処理できます(ただし、POSIX準拠の正規表現エンジンではtheを達成できません)。
(\b\w+\b)\W+\1
以下のREでこれを試してください
()*もう一度繰り返す
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();
}
いいえ。それは不規則な文法です。使用できるエンジン/言語固有の正規表現があるかもしれませんが、それを行うことができる普遍的な正規表現はありません。
これは、複数の単語を複数回キャッチするものです。
(\b\w+\b)(\s+\1)+
これは、Twitchボットの重複フレーズを削除するために使用する正規表現です。
(\S+\s*)\1{2,}
(\S+\s*)
は、空白ではなく、空白に続く文字列を探します。
\1{2,}
は、一致する文字列でそのフレーズの3つ以上のインスタンスを探します。同一のフレーズが3つある場合、一致します。
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]と同等です。その制限を気にしない場合、受け入れられる答えは結構です。
この表現(上記の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
一部の開発者は、重複する連続する非空白部分文字列だけでなく、3つ以上の重複文字列を排除するソリューションを求めてこのページに来ているので、適応パターンを示します。
パターン:/(\b\S+)(?:\s+\1\b)+/
( Pattern Demo )
Replace:$1
(キャプチャ文字列#1との完全な文字列の置換)
このパターンは、「空白全体」の非空白部分文字列に貪欲に一致し、1つ以上の空白文字(スペース、タブ、改行など)で区切られた一致部分文字列の1つ以上のコピーを必要とします。
具体的には:
\b
(単語境界)文字は、単語の一部が一致しないようにするために不可欠です。+
(1つ以上の量指定子)は、*
が正規表現エンジンを "bother"してシングルトンオカレンスをキャプチャおよび置換するため、*
よりも適切です。無駄なパターン設計。*文や句読点を含む入力文字列を扱う場合は、パターンをさらに改良する必要があります。
重複する単語の大文字と小文字を区別しないチェックが必要な場合に使用します。
(?i)\\b(\\w+)\\s+\\1\\b
次の式は、連続した単語をいくつでも見つけるために正しく機能するはずです。マッチングでは大文字と小文字が区別されない場合があります。
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の最初のインスタンスに置き換えます。