9

この入力文字列があります(タブ、スペース、改行を含む):


        That      is a test.              
    seems to work       pretty good? working.








    Another test  again.

[編集]: stackoverflow はすべての特殊文字 (タブなど) を削除するため、より良いテストのために文字列を提供する必要がありました。

String testContent = "\n\t\n\t\t\t\n\t\t\tDas      ist ein Test.\t\t\t  \n\tsoweit scheint das \t\tganze zu? funktionieren.\n\n\n\n\t\t\n\t\t\n\t\t\t      \n\t\t\t      \n    \t\t\t\n    \tNoch ein  Test.\n    \t\n    \t\n    \t";

そして、私はこの状態に到達したい:


That is a test.
seems to work pretty good? working.
Another test again.

String expectedOutput = "Das ist ein Test.\nsoweit scheint das ganze zu? funktionieren.\nNoch ein Test.\n";

何か案は?これは正規表現を使用して達成できますか?

replaceAll("\\s+", " ")私が探しているものではありません。この正規表現が存在するものの正確に1つの改行を保持する場合、それは完璧です.

私はこれを試しましたが、これは私には最適ではないようです...:

BufferedReader bufReader = new BufferedReader(new StringReader(testContent));
String line = null;
StringBuilder newString = new StringBuilder();
while ((line = bufReader.readLine()) != null) {
    String temp = line.replaceAll("\\s+", " ");
    if (!temp.trim().equals("")) {
        newString.append(temp.trim());
        newString.append("\n");
    }
}
4

5 に答える 5

15

単一の正規表現 (およびタブ用の小さなパッチ):

input.replaceAll("^\\s+|\\s+$|\\s*(\n)\\s*|(\\s)\\s*", "$1$2")
     .replace("\t"," ");

正規表現は難しそうに見えますが、実際には OR で結合された次の部分にうまく分解されます。

  • ^\s+– 先頭の空白に一致。
  • \s+$– 末尾の空白に一致します。
  • \s*(\n)\s*– 改行を含む空白に一致し、その改行をキャプチャします。
  • (\s)\s*– 最初の空白文字をキャプチャして、空白を照合します。

結果は 2 つのキャプチャ グループと一致しますが、一度に空でないグループは 1 つだけです。これにより、一致を に置き換えることができます"$1$2"。これは、「2 つのキャプチャ グループを連結する」ことを意味します。

残っている唯一の問題は、このアプローチを使用してタブをスペースに置き換えることができないことです。そのため、単純な正規表現以外の文字の置き換えで修正します。

于 2013-03-19T09:05:56.560 に答える
6

4つのステップで:

text
    // 1. compress all non-newline whitespaces to single space
    .replaceAll("[\\s&&[^\\n]]+", " ")
    // 2. remove spaces from begining or end of lines
    .replaceAll("(?m)^\\s|\\s$", "")
    // 3. compress multiple newlines to single newlines
    .replaceAll("\\n+", "\n")
    // 4. remove newlines from begining or end of string
    .replaceAll("^\n|\n$", "") 
于 2013-03-19T09:00:32.573 に答える
2

最初にすべての新しい行1つの新しい行に置き換え、次にスペースを置き換えますが、新しい行は置き換えません。最後に、文字列の先頭からすべての空白を削除する必要があります。

String test = "      This is              a real\n\n\n\n\n\n\n\n\n test !!\n\n\n   bye";
test = test.replaceAll("\n+", "\n");
test = test.replaceAll("((?!\n+)\\s+)", " ");
test = test.replaceAll("((?!\n+)\\s+)", "");

出力:

This is a real
test !!
bye
于 2013-03-19T08:49:24.083 に答える
2

やってみませんか

String[] lines = split(s,"\n")
String[] noExtraSpaces = removeSpacesInEachLine(lines)
String result = join(noExtraSpaces,"\n")

https://softwareengineering.stackexchange.com/questions/10998/what-does-the-jamie-zawinskis-quotation-about-regular-expressions-meanを忘れないでください

于 2013-03-19T08:48:10.157 に答える
2

私の理解が正しければ、一連の改行を 1 つの改行に置き換えたいだけです。したがって、(適切なフラグで)置き換え\n\n*ます\n。行に空白が多い場合は、最初に空白を削除して (^\s\s*$複数行モードで)、改行を置き換えます。

編集:ここでの唯一の問題は、いくつかの改行があちこちに残る可能性があることです。そのため、最初にスペースを折りたたんでから、空の行の問題を修正するように注意する必要があります。おそらく単一の正規表現にさらに切り詰めることができますが、次の 3 つを使用すると読みやすくなります。

 Pattern spaces = Pattern.compile("[\t ]+");
 Pattern emptyLines = Pattern.compile("^\\s+$?", Pattern.MULTILINE);
 Pattern newlines = Pattern.compile("\\s*\\n+");
 System.out.print(
      newlines.matcher(emptyLines.matcher(spaces.matcher(
        input).replaceAll(" ")).replaceAll("")).replaceAll("\n"));
于 2013-03-19T08:45:48.503 に答える