どのように第二、第三に置き換える/試合に私の正規表現を変更するには、...言葉ではなく、最初の1に?

バヌアレブAunav:

タスクは、コンテナクラスを使用せずに正規表現を使用して解決しなければなりません。

入力:テキスト(ラテン語とキリル文字からなるものであってもよい、が含まれていません_

出力:ソーステキスト、しかしに先行はすべてアンダースコアで単語を繰り返し、 _

文字のみを含む配列などの単語を考慮すること(他のすべての文字が単語に含まれません)。入力を出力に変換し、静的なコンバート方法を作成します。

完全に方法:

public static String convert (String input) {
    ...
}

入力例:

This is a test
And this is also a test
And these are also tests
test
Это тест
Это также тест
И это также тесты

出力例:

This _is _a _test
_And this _is _also _a _test
_And these are _also tests
_test
_Это _тест
_Это _также _тест
И это _также тесты

私の試み:

public static void convert(String input) {
        Pattern p = Pattern.compile("(\\b\\w+\\b)(?=[\\s\\S]*\\b\\1\\b[\\s\\S]*\\b\\1\\b)", Pattern.UNICODE_CHARACTER_CLASS);
        String res = p.matcher(input+" "+input).replaceAll("_$1");
        res = res.substring(0, res.length() - 1 - p.matcher(input).replaceAll("_$1").length());
        System.out.println(res);
    }

私の出力:ここに画像の説明を入力します。

This _is _a _test
_And this _is _also _a test
_And these are _also tests
_test
_Это _тест
_Это _также _тест
И это _также тесты

単語「_」なしの2行目の「テスト」が、私は「_test」を必要と

Wiktor第Stribiżav:

あなたはすべての繰り返しの単語を収集し、その後でそれらを付加します_

// Java 9+
String s = "This is a test\nAnd this is also a test\nAnd these are also tests\ntest\nЭто тест\nЭто также тест\nИ это также тесты";
String rx = "(?sU)\\b(\\w+)\\b(?=.*\\b\\1\\b)";
String[] results = Pattern.compile(rx).matcher(s).results().map(MatchResult::group).toArray(String[]::new);
System.out.println(s.replaceAll("(?U)\\b(?:" + String.join("|", results) + ")\\b", "_$0"));

// Java 8
String s = "This is a test\nAnd this is also a test\nAnd these are also tests\ntest\nЭто тест\nЭто также тест\nИ это также тесты";
String rx = "(?sU)\\b(\\w+)\\b(?=.*\\b\\1\\b)";
List<String> matches = new ArrayList<>();
Matcher m = Pattern.compile(rx).matcher(s);
while (m.find()) {
    matches.add(m.group());
}
System.out.println(s.replaceAll("(?U)\\b(?:" + String.join("|", matches) + ")\\b", "_$0"));

参照してください。Javaはオンラインデモ第二のスニペットのデモ出力:

This _is _a _test
_And this _is _also a _test
And these are _also tests
test
_Это _тест
_Это _также тест
И это _также тесты

私が交換に注意[\s\S]してこの問題を回避する構造物を.と組み合わせsDOTALL埋め込まれたフラグオプション(つまりので.、あまりにも、改行を一致させることができ)、使用するJava 9+ .results()すべての一致を返すメソッドとを接合た試合のうち、最終パターンを建て|OR交代演算子。

細部

  • (?sU)\b(\w+)\b(?=.*\b\1\b)
    • (?sU)-組み込みDOTALL(作るには.あまりにも、改行にマッチ)とUNICODE_CHARACTER_CLASSはフラグオプション(すべての速記のUnicodeを意識します)
    • \b - ワード境界
    • (\w+)-グループ1:1+ワード文字、文字、数字または_S
    • \b - ワード境界
    • (?=.*\b\1\b) - すぐ右に、単語全体として、グループ1の場合と同じ値で、その後、できるだけ多くのように、任意の0+文字がなければなりません。
  • (?U)\\b(?:" + String.join("|", results) + ")\\b":このパターンは次のようになります (?U)\b(?:test|is|Это|тест|также)\b
    • (?U) - 組み込みUNICODE_CHARACTER_CLASSフラグオプション
    • \b - ワード境界
    • (?:test|is|Это|тест|также) - 非キャプチャ交代グループ
    • \b - ワード境界

置換がある_$0ように、第2の正規表現のための_全体の一致値に追加され、$0

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=313171&siteId=1
おすすめ