正規表現の質問-引用符で囲まれたテキストブロックの外側の1つ以上のスペース

StackOverflow https://stackoverflow.com/questions/263985

  •  06-07-2019
  •  | 
  •  

質問

複数のスペースの出現を単一のスペースに置き換えたいが、引用符の間のテキストではアクションを実行しない。

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

役に立ちましたか?

解決

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

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

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

他のヒント

他の何かに含まれる可能性があるものと一致させようとする場合、次のように、両方に一致する正規表現を作成すると役立ちます。

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

これは、引用符で囲まれた文字列または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 );

引用符の間のテキスト:引用符は同じ行に含まれていますか、それとも複数行ですか?

トークン化し、トークン間に単一のスペースを出力します。 「引用符を処理するJavaトークナイザー」のクイックGoogle起きた: このリンク

YMMV

編集:そのリンクは好きではありませんでした。 Google検索リンクは次のとおりです。 google 。それが最初の結果でした。

個人的に、私は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

引用されたコンテンツを解析した後、必要に応じて、これをバルクで、またはピースごとに実行します。

String text = "ABC   DEF GHI   JKL";
text = text.replaceAll("( )+", " ");
// text: "ABC DEF GHI JKL"

ジェフ、あなたは正しい道を進んでいますが、コードにはいくつかのエラーがあります。つまり、(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() );
  }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top