Jakarta ORO

いまさらですが、ちょっとOROを使って置換でもしてみました。


以下のサンプルはhtml中のリンクを下線付き青文字に変換します。
</ a>とかスペースが入るだけで置換できない貧弱ロジックですが、あくまで、ORO、正規表現の話ということで。


正規表現部分の説明

  1. /〜/is
    • 〜にマッチするものを対象とし、i指定だから大文字小文字を区別しない。
  2. (〜)
    • 〜にマッチしたものを記録する。
  3. <a\\s+[^<]+>
    • 「<a」で始まり、スペースが1個以上続き「<」以外の文字が1つ以上続く文字列。
  4. [^<]+
    • 「<」以外の文字が1つ以上続く文字列。
  5. </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で使いまわしがいい感じです。