Jakarta ORO
いまさらですが、ちょっとOROを使って置換でもしてみました。
以下のサンプルはhtml中のリンクを下線付き青文字に変換します。
</ a>とかスペースが入るだけで置換できない貧弱ロジックですが、あくまで、ORO、正規表現の話ということで。
正規表現部分の説明
- /〜/is
- 〜にマッチするものを対象とし、i指定だから大文字小文字を区別しない。
- (〜)
- 〜にマッチしたものを記録する。
- <a\\s+[^<]+>
- 「<a」で始まり、スペースが1個以上続き「<」以外の文字が1つ以上続く文字列。
- [^<]+
- 「<」以外の文字が1つ以上続く文字列。
- </a>
- 「</a>」が続く文字列。
import org.apache.oro.text.perl.Perl5Util; import org.apache.oro.text.regex.Perl5Compiler; public class Test { private static Perl5Util perl = new Perl5Util(); private static String html = "<html>\n" + "<head></head>\n" + "<body>\n" + "foofoofoo...\n" + "<a href=\"home.html\">HOME</a>\n" + "<a href=\"about.html\">ABOUT</a>\n" + "<a href=\"gallery.html\">GALLERY</a>\n" + "<a href=\"blog.html\">BLOG</a>\n" + "<a href=\"contact.html\">CONTACT US</a>\n" + "barbarbar...\n" + "</body>\n" + "</html>"; public static void main(String[] args) { System.out.println(html); System.out.println("=============================="); System.out.println(sanitizeLink(html)); } public static String sanitizeLink(String html) { synchronized (Test.class) { while (perl.match("/(<a\\s+[^<]+>([^<]+)</a>)/i", html)) { String pattern1 = "s#"+ Perl5Compiler.quotemeta(perl.group(1)) + "#" + Perl5Compiler.quotemeta("<font color=\"blue\"><u>" + perl.group(2) + "</u></font>") + "#i"; html = perl.substitute(pattern1, html); } return html; } } }
実行すると以下のようにリンク<a>が、下線付き青文字<font><u>になっていますね。
<html> <head></head> <body> foofoofoo... <a href="home.html">HOME</a> <a href="about.html">ABOUT</a> <a href="gallery.html">GALLERY</a> <a href="blog.html">BLOG</a> <a href="contact.html">CONTACT US</a> barbarbar... </body> </html> ======================== <html> <head></head> <body> foofoofoo... <font color="blue"><u>HOME</u></font> <font color="blue"><u>ABOUT</u></font> <font color="blue"><u>GALLERY</u></font> <font color="blue"><u>BLOG</u></font> <font color="blue"><u>CONTACT US</u></font> barbarbar... </body> </html>
ところで、Perl5Utilはスレッドセーフじゃないです。
sanitizeLinkメソッドが複数のスレッドから同時呼び出しを受けるとして、普通に作ると、sanitizeLinkメソッド内でPerl5Utilインスタンスを毎回newしたいところですが、これがかなり負荷高いです。
以前スレッドの排他の最後にも書きましたが、1回newしてsynchronizedで使いまわしがいい感じです。