home wiki.fukuchiharuki.me
Menu

  • 追加された行はこの色です。
  • 削除された行はこの色です。
*はじめに [#va2cc46a]
Javaも正規表現をサポートしていて
Perlと同等の処理をすることができる(らしい。)
ここでは、正規表現を使ってパターンマッチする部分文字列について
条件を当てながら置換する方法について記載する。

*想定するケース [#v6b4e8b1]
「テキスト中のリンクのうち、
外部サイトを参照するものを別ウィンドウに表示する」
ケースを考える。
つまり
「テキスト中のアンカタグのうち、
参照URLがある条件を満たす場合のみ target="_blank" を挿入する」
と言い換えることができる。

要件を抜き出すと、
-テキスト中からアンカタグを抜き出す
-抜き出した文字列のうち参照URL部分について条件を当てる
-条件を満たした場合抜き出したアンカタグに target="\blank" を挿入する

となる。

*実装 [#b5a03679]
 String regex = "(<a .*?href=[\"'])(.*?)([\"'])(.*?>)"; // アンカタグを抜き出す正規表現
 StringBuffer tunedText = new StringBuffer(); // 置き換え後のテキスト
 Pattern pattern = Pattern.compile(regex);
 Matcher matcher = pattern.matcher(text); // textは置き換え前のテキスト
 while (matcher.find()) {
   if (! matcher.group(2).matches("^(http|https|ftp)://([^\\./]+\\.)*foo\\.bar(/.*)?$")) {
     matcher.appendReplacement(tunedText, 
                               matcher.group(1)      // 「<a href="(アンカタグの先頭)」
                             + matcher.group(2)      // 「(URL)」
                             + matcher.group(3)      // 「"(hrefの閉じ)」
                             + " target=\"_blank\" " // 「target="_blank"(固定)」
                             + matcher.group(4));    // 「>(アンカタグの末尾)」
   }
 }
 matcher.appendTail(tunedText);

**テキスト中からアンカタグを抜き出す [#r847afc6]
アンカタグを抜き出す正規表現を
 (<a .*?href=[\"'])(.*?)([\"'])(.*?>)
としている。

ここでは抜き出すアンカタグを次の要素に分割している。
-「<a href="(アンカタグの先頭)」
-「(URL)」
-「"(hrefの閉じ)」
-「>(アンカタグの末尾)」

**抜き出した文字列のうち参照URL部分について条件を当てる [#b68ad166]
分割した要素「(URL)」について条件を当てる。ここでは、
 if (! matcher.group(2).matches("^(http|https|ftp)://([^\\./]+\\.)*foo\\.bar(/.*)?$"))
としている(条件は「foo.bar」をドメイン名とするURL以外の場合。)

**条件を満たした場合抜き出したアンカタグに target="\blank" を挿入する [#tedb0bc3]
分割した要素「"(hrefの閉じ)」と「>(アンカタグの末尾)」の間に
「target="_blank"(固定)」を挿入して appendReplacement() している。

ここで appendReplacement() はカーソルの先頭からマッチした文字列の末尾までをアペンドし、
カーソルをマッチした文字列の末尾の次の文字に変更する。
従って、appendReplacement() を繰り返すことで
マッチした文字列の末尾までを次々にアペンドできる。
最後に appendTail() をコールすることで、
最後にマッチした文字列の次の文字から後ろをアペンドする。