2

複数のスペースを単一のスペースに置き換えたいのですが、引用符の間のテキストでは何もしません。

Java正規表現でこれを行う方法はありますか? もしそうなら、試してみるか、ヒントを教えてください。

4

7 に答える 7

4

これは、先読みを使用して、現在の位置の後のすべての引用符が一致するペアになることを決定する別のアプローチです。

text = text.replaceAll("  ++(?=(?:[^\"]*+\"[^\"]*+\")*+[^\"]*+$)", " ");

必要に応じて、引用されたセクション内のエスケープされた引用符を処理するように先読みを調整できます。

于 2008-11-05T06:42:29.427 に答える
2

他の何かに含めることができるものと一致させようとする場合、次のように、両方に一致する正規表現を作成すると便利です。

("[^"\\]*(?:\\.[^"\\]*)*")|(  +)

これは、引用符で囲まれた文字列または 2 つ以上のスペースに一致します。2 つの式が結合されているため、引用符で囲まれた文字列または 2 つ以上のスペースには一致しますが、引用符内のスペースには一致しません。この式を使用すると、各一致を調べて、引用符で囲まれた文字列か 2 つ以上のスペースかを判断し、それに応じて処理する必要があります。

Pattern spaceOrStringRegex = Pattern.compile( "(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|(  +)" );

StringBuffer replacementBuffer = new StringBuffer();

Matcher spaceOrStringMatcher = spaceOrStringRegex.matcher( text );

while ( spaceOrStringMatcher.find() ) 
{
    // if the space group is the match
    if ( spaceOrStringMatcher.group( 2 ) != null ) 
    {
        // replace with a single space
        spaceOrStringMatcher.appendReplacement( replacementBuffer, " " );
    }
}

spaceOrStringMatcher.appendTail( replacementBuffer );
于 2008-11-05T00:54:02.860 に答える
0

引用されたコンテンツを解析した後、必要に応じて、残りのコンテンツに対してこれを一括で、または少しずつ実行します。

String text = "ABC   DEF GHI   JKL";
text = text.replaceAll("( )+", " ");
// text: "ABC DEF GHI JKL"
于 2008-11-05T05:12:24.163 に答える
0

それをトークン化し、トークン間に単一のスペースを発行します。「引用符を処理するJavaトークナイザー」のクイックグーグルが表示されました: このリンク

YMMV

編集:そのリンクが気に入らなかった. Google 検索リンクは次のとおりです: google . 初めての結果でした。

于 2008-11-05T00:58:29.230 に答える
0

ジェフ、あなたは正しい道を進んでいますが、コードにいくつかのエラーがあります。(1) 否定された文字クラス内の引用符をエスケープするのを忘れました。(2) 最初のキャプチャ グループ内の括弧は、非キャプチャ バリエーションである必要があります。(3) キャプチャ用括弧の 2 番目のセットが一致に参加しない場合は、group(2)null が返され、それをテストしていません。(4) 正規表現で1 つ以上の ではなく2 つ以上のスペースをテストする場合、後で一致の長さを確認する必要はありません。改訂されたコードは次のとおりです。

import java.util.regex.*;

public class Test
{
  public static void main(String[] args) throws Exception
  {
    String text = "blah    blah  \"boo   boo boo\"  blah  blah";
    Pattern p = Pattern.compile( "(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|(  +)" );
    StringBuffer sb = new StringBuffer();
    Matcher m = p.matcher( text );
    while ( m.find() ) 
    {
      if ( m.group( 2 ) != null ) 
      {
        m.appendReplacement( sb, " " );
      }
    }
    m.appendTail( sb );
    System.out.println( sb.toString() );
  }
}
于 2008-11-05T06:14:35.427 に答える
0

個人的には、私は Java を使用しませんが、この RegExp はトリックを行うことができます:

([^\" ])*(\\\".*?\\\")*

RegExBuddy で式を試すと、次のコードが生成されます。

try {
    Pattern regex = Pattern.compile("([^\" ])*(\\\".*?\\\")*", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    Matcher regexMatcher = regex.matcher(subjectString);
    while (regexMatcher.find()) {
        for (int i = 1; i <= regexMatcher.groupCount(); i++) {
            // matched text: regexMatcher.group(i)
            // match start: regexMatcher.start(i)
            // match end: regexMatcher.end(i)

            // I suppose here you must use something like
            // sstr += regexMatcher.group(i) + " "
        }
    }
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

少なくとも、Python では問題なく動作するようです。

import re

text = """
este  es   un texto de   prueba "para ver  como se comporta  " la funcion   sobre esto
"para ver  como se comporta  " la funcion   sobre esto  "o sobre otro" lo q sea
"""

ret = ""
print text  

reobj = re.compile(r'([^\" ])*(\".*?\")*', re.IGNORECASE)

for match in reobj.finditer(text):
    if match.group() <> "":
        ret = ret + match.group() + "|"

print ret
于 2008-11-05T01:28:40.077 に答える
0

引用符の間のテキスト: 引用符は同じ行または複数の行にありますか?

于 2008-11-05T00:44:27.387 に答える