9

単語以外のすべての文字の文字列をクリーンアップしようとしています。ただし、パターンが次のようになっている場合を除きます。&[\w]+;

例えば:

abc; => abc
abc & => abc &
abc& => abc  

私が使用する場合、それは私が望まない2番目の例からもstring.replaceAll("\W","") 削除;します。'&'

この問題でネガティブルックアヘッドを使用すると、迅速なソリューションの正規表現パターンを得ることができますか?

4

3 に答える 3

2

まず第一に、私はその質問が本当に好きです。さて、あなたが望むことは単一で行うことができませんでした。そのためには、可変長replaceAllのが必要になるため、これは許可されていません。negative look-behindそれが許されていれば、それほど難しくはなかっただろう。

とにかく、ここではシングルreplaceAllはオプションではないので、ここで少しハックすることができます。semi-colon最初に最後の文字列をいくつかの文字シーケンスに置き換えるのと同じentity referenceように、文字列の残りの部分などには必ず存在しませんXXX。私はこれが正しくないことを知っています、しかしあなたは確かにそれを助けることができません。

だから、これがあなたが試すことができるものです:

String str = "a;b&c &";

str  = str.replaceAll("(&\\w+);", "$1XXX")
          .replaceAll("&(?!\\w+?XXX)|[^\\w&]", "")
          .replaceAll("(&\\w+)XXX", "$1;");

System.out.println(str);

説明:

  • 最初のreplaceAllは、のようなパターン&&ampXXXまたは最後に置き換えられた他のシーケンスを置き換え;ます。
  • 2番目のreplaceAllは、&その後にない文字\\w+XXX、または任意のnon-word, non &文字を置き換えます。これは、ある種のパターン&'sの一部ではないすべてのものを置き換えます。&さらに、他の単語以外の文字も置き換えます。
  • 3番目のreplaceAllは、から再作成するために、に再置換XXXします;&&ampXXX

そして、理解しやすくするために、PatternクラスMatcherを使用することもできます。置換基準が複雑な場合は、常にそれらを使用することをお勧めします。

String str = "a;b&c &";

Pattern pattern = Pattern.compile("&\\w+;|[^\\w]");
Matcher matcher = pattern.matcher(str);

StringBuilder sb = new StringBuilder();

while (matcher.find()) {
    String match = matcher.group();
    if (!match.matches("&\\w+;")) {
        matcher.appendReplacement(sb, "");
    } else {
        matcher.appendReplacement(sb, match);
    }
}
matcher.appendTail(sb);
System.out.println(sb.toString());

これは@Ericのコードに似ていますが、それを一般化したものです。それはもちろん、そこに投げ込まれたもの&を取り除くために改善された場合にのみ機能します。NullPointerException

于 2013-02-14T18:46:37.353 に答える
2

単純なString.replaceAllを使用してこれを実行できるかどうかはわかりません。おそらく、パターンマッチャーを使用して一致をループし、手動で検索して置換する必要があります。次のコードのようなものでうまくいくはずです。

public String replaceString(String origString) {
    Pattern pattern = Pattern.compile("&(\w+);|[^\w]");
    Matcher matcher = pattern.matcher(origString);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
        if (matcher.group().startsWith("&") && !matcher.group(1).equals("amp")) {
            matcher.appendReplacement(sb, matcher.group());
        } else {
            matcher.appendReplacement(sb, "");
        }
    }
    matcher.appendTail(sb);
    return sb.toString();
}
于 2013-02-14T18:38:54.943 に答える
0

次のようなネガティブな先読みを使用することをお勧めします。

string.replace(/&(?!\w+;)/ig, '');

これは、セミコロンで終わる単語文字が後に続くすべての&notを置き換えます。

編集(Java):

string.replaceAll("/&(?!\w+;)/i", '');
于 2013-02-14T18:24:54.800 に答える