1

私は正規表現は初めてですが、これが私の解決策の方法だと思います。任意の HTML スニペットを取得して、イメージ タグをカスタマイズしようとしています。例えば、

この HTML コードがある場合: <><><><><img src="blah.jpg"><><><><><><><><img src="blah2.jpg"><><><>

私はそれを次のように変えたい: <><><><><img src="images/blah.jpg"><><><><><><><><img src="images/blah2.jpg"><><><>

私が今持っているコードはこれです:

Pattern p = Pattern.compile("<img.*src=\".*\\..*\"");
Matcher m = p.matcher(htmlString);
boolean b = m.find();

String imgPath = "src=\"images/";

while(b)
{
    //Get file name.
    String name="test.jpg\"";

    //Assign new path.
    m.group().replaceAll("src=\".*\"",imgPath+name);
}
4

4 に答える 4

8

正規表現は、HTML を解析する正しい方法ではありません。 やらないでください。正しく行うことはできません。

適切なパーサーを使用してください。

Document doc = Jsoup.parse(someHtml);
Elements imgs = doc.select("img");
for (Element img : imgs) {
    img.attr("src", "images/" + img.attr("src")); // or whatever
}

doc.outerHtml(); // returns the modified HTML
于 2013-10-02T03:56:43.707 に答える
3

このコードはほぼ完璧です。大量の情報が出力されるので、「最終結果」と「オリジナル」と表示されている場所を探して、IMG タグをカスタマイズした結果を確認してください。まだ修正方法がわからない小さな欠陥があります。「in10」は、入力文字列をテストするための変数です。残りは正規表現です。

改行文字を使用したり、"src=\"\"" または "src=''" の代わりに "src=" を空白のままにしたりすると、問題が発生することに気付きました。引用符が結果に影響しているようです。

private static String r16 = "(?s)(<img.*?)(src\\s*?=\\s*?(?:\"|').*?(?:\"|'))";
private static String in10 = "<><><><><img width=1 height=888 src=\"bnm.jpg\"<><><><><img src=\"\"> <img src = \"\"><img src ='folder1/folder2/bnm.jpg'><><><img src =\"'>";
private static String r14 = "(?s)\\/|\\=";




    String path="images/";
    String name="";

   Pattern p = Pattern.compile(r16);

   Matcher m = p.matcher(in10); 


   StringBuffer sb = new StringBuffer();
   int i=1;
   while(m.find())
   {
        String g0 = m.group();
        String g2 = m.group(2);
        System.out.println("Main group"+i+":"+g0);
        System.out.println("Inner group1:"+m.group(1));
        System.out.println("Inner group2:"+g2);




            String[] names=g2.split(r14);
            printNames(names);

            /*
             * src="/folder1/folder2/blah.jpg"  --->  blah.jpg
             * src="bnm.jpg"                    --->  src="bnm.jp"
             */

            if(names.length>=1)
            {
                name = names[names.length-1];
            }
            else
            {
                name = "";
            }
        //Name might be empty string.
        name = name.replaceAll("\"|'","");
        System.out.println("Retrieved Name:"+name);
        m.appendReplacement(sb,"$1src=\""+path+name+"\"");
        i++;
   }
   m.appendTail(sb);
    INPUT=sb.toString();
   System.out.println("Final Result:"+INPUT);
   System.out.println("Original____:"+in10);
   System.out.println("Count:"+m.groupCount());        
}
于 2013-10-01T04:39:24.847 に答える
0

正規表現でこれを行うのは html フラグメントを変更するのに間違った方法であるという他の意見には同意しますが、Java で src 要素をパターンに置き換える方法を示す JUnit テスト ケースを次に示します。

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

import org.junit.Test;

public class ImgSrcReplace {

  @Test
  public void replaceWithRegex() {
    String dir = "image/";
    String htmlFragment = "<body>\n"+
    "<img src=\"single-line.jpg\">"+
    "<img src=\n"+
    "\"multiline.jpg\">\n"+
    "<img src='single-quote.jpg'><img src=\"broken.gif\'>"+
    "<img class=\"before\" src=\"class-before.jpg\">"+
    "<img src=\"class-after.gif\" class=\"after\">"+
    "</body>";


    Pattern replaceImgSrc =
      Pattern.compile(
        "(<img\\b[^>]*\\bsrc\\s*=\\s*)([\"\'])((?:(?!\\2)[^>])*)\\2(\\s*[^>]*>)",
        Pattern.CASE_INSENSITIVE&Pattern.MULTILINE);

    String result = 
      replaceImgSrc.matcher(htmlFragment)
        .replaceAll("$1$2"+Matcher.quoteReplacement(dir)+"$3$2$4");

    assertThat("the single line image tag was updated", result, 
      containsString("image/single-line.jpg"));
    assertThat("the multiline image tag was updated", result, 
      containsString("image/multiline.jpg"));
    assertThat("the single quote image tag was updated", result, 
      containsString("image/single-quote.jpg"));
    assertThat("the broken gif was ignored.", result, 
      containsString("\"broken.gif'"));
    assertThat("attributes before are preseved.", result, 
      containsString("<img class=\"before\" src=\"image/class-before.jpg\">"));
    assertThat("attributes after are preseved.", result, 
      containsString("<img src=\"image/class-after.gif\" class=\"after\">"));
  }

}
于 2013-10-03T16:05:06.083 に答える
0

これには正規表現を使用しないでください.josh3736が言った方法は堅牢です.しかし、正規表現を使用したい場合は、次を使用する必要があります:

String s = "<><><><><img src=\"blah.jpg\"><><><><><><><><img src=\"blah2.jpg\"><><><>";
s = s.replaceAll("(?<=img src=\")([^\"]+)(?=\">)","images/$1");
System.out.println(s);

出力:

<><><><><img src="images/blah.jpg"><><><><><><><><img src="images/blah2.jpg"><><><>
于 2013-10-02T17:46:18.943 に答える