0

以下に示すような値を含む文字列があります。特定のcustomerIdを含むhtmlimgタグを新しいテキストに置き換えたい 。期待どおりの出力が得られない小さなJavaプログラムを試しました。プログラム情報は次のとおりです。

私の入力文字列は

 String inputText = "Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123/></p>"
    + "<p>someText</p><img src=\"getCustomers.do?custCode=2&customerId=3340&param2=456/> ..Ending here";

正規表現は

  String regex = "(?s)\\<img.*?customerId=3340.*?>";

入力文字列内に入れたい新しいテキスト

編集開始:

String newText = "<img src=\"getCustomerNew.do\">";

編集終了:

今私はやっています

  String outputText = inputText.replaceAll(regex, newText);

出力は

 Starting here.. Replacing Text ..Ending here

しかし、私の期待される出力は

 Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123/></p><p>someText</p>Replacing Text ..Ending here

予想される出力では、customerId=3340を含むimgタグのみがReplacingTextに置き換えられていることに注意してください。出力で両方のimgタグが置き換えられる理由がわかりませんか?

4

3 に答える 3

4

そこに「ワイルドカード」/「任意の」パターン(.*)があり、一致する文字列を可能な限り長くします。パターンの最後の固定テキストは文字であるため、入力テキスト>の最後の文字と一致します。 >、つまり最後のもの!

マッチングが最初の文字を超えない.*ようにパーツを次のように変更することで、これを修正できるはずです。[^>]+>

正規表現を使用してHTMLを解析すると、問題が発生します。

于 2012-12-13T18:18:15.417 に答える
1

他の人がコメントであなたに言ったように、HTMLは正規言語ではないので、それを操作するために正規表現を使用することは通常苦痛です。最善のオプションは、HTMLパーサーを使用することです。私はこれまでJsoupを使用したことがありませんが、少しグーグルすると、次のようなものが必要なようです。

import org.jsoup.*;
import org.jsoup.nodes.*;
import org.jsoup.select.*;

public class MyJsoupExample {
    public static void main(String args[]) {
        String inputText = "<html><head></head><body><p><img src=\"getCustomers.do?custCode=2&customerId=3334&param1=123\"/></p>"
            + "<p>someText <img src=\"getCustomers.do?custCode=2&customerId=3340&param2=456\"/></p></body></html>";
        Document doc = Jsoup.parse(inputText);
        Elements myImgs = doc.select("img[src*=customerId=3340");
        for (Element element : myImgs) {
            element.replaceWith(new TextNode("my replaced text", ""));
        }
        System.out.println(doc.toString());
    }
}

基本的に、コードは指定された文字列を含む属性をimg持つノードのリストを取得しますsrc

Elements myImgs = doc.select("img[src*=customerId=3340");

次に、リストをループして、それらのノードをテキストに置き換えます。

アップデート

ノード全体をテキストに置き換えたくないimgが、代わりにその属性に新しい値を指定する必要がある場合は、ループsrcのブロックを次のように置き換えることができます。for

element.attr("src", "my new value"));

または、値の一部だけを変更したい場合は、次のsrcようにすることができます。

String srcValue = element.attr("src");
element.attr("src", srcValue.replace("getCustomers.do", "getCustonerNew.do"));

これは私がこのスレッドに投稿したものと非常によく似ています。

于 2012-12-13T19:52:33.283 に答える
0

何が起こるかというと、正規表現は最初のimgタグの照合を開始し、 customerId = 3340が見つかるまですべてを消費し(貪欲かどうかに関係なく)、>が見つかるまですべてを消費し続けます。

customerId = 3340のimgだけを使用したい場合は、このタグが一致する可能性のある他のタグと何が違うのかを考えてください。

この特定のケースでは、考えられる解決策の1つは、後読み演算子(一致を消費しない)を使用して、そのimgタグの背後にあるものを調べることです。この正規表現は機能します:

String regex = "(?<=</p>)<img src=\".*?customerId=3340.*?>";
于 2012-12-15T15:47:35.660 に答える