- 履歴一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- Java/正規表現を使って条件付きで置き換える へ行く。
- 1 (2011-03-09 (水) 09:02:11)
- 2 (2011-03-09 (水) 09:04:22)
- 3 (2011-03-10 (木) 11:42:23)
- 4 (2011-03-12 (土) 10:44:30)
- 5 (2013-08-17 (土) 09:07:15)
はじめに†
Javaも正規表現をサポートしていて Perlと同等の処理をすることができる(らしい。) ここでは、正規表現を使ってパターンマッチする部分文字列について 条件を当てながら置換する方法について記載する。
想定するケース†
「テキスト中のリンクのうち、 外部サイトを参照するものを別ウィンドウに表示する」 ケースを考える。 つまり 「テキスト中のアンカタグのうち、 参照URLがある条件を満たす場合のみ target="_blank" を挿入する」 と言い換えることができる。
要件を抜き出すと、
- テキスト中からアンカタグを抜き出す
- 抜き出した文字列のうち参照URL部分について条件を当てる
- 条件を満たした場合抜き出したアンカタグに target="\blank" を挿入する
となる。
実装†
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);
テキスト中からアンカタグを抜き出す†
アンカタグを抜き出す正規表現を
(<a .*?href=[\"'])(.*?)([\"'])(.*?>)
としている。
ここでは抜き出すアンカタグを次の要素に分割している。
- 「<a href="(アンカタグの先頭)」
- 「(URL)」
- 「"(hrefの閉じ)」
- 「>(アンカタグの末尾)」
抜き出した文字列のうち参照URL部分について条件を当てる†
分割した要素「(URL)」について条件を当てる。ここでは、
if (! matcher.group(2).matches("^(http|https|ftp)://([^\\./]+\\.)*foo\\.bar(/.*)?$"))
としている(条件は「foo.bar」をドメイン名とするURL以外の場合。)
条件を満たした場合抜き出したアンカタグに target="\blank" を挿入する†
分割した要素「"(hrefの閉じ)」と「>(アンカタグの末尾)」の間に 「target="_blank"(固定)」を挿入して appendReplacement() している。
ここで appendReplacement() はカーソルの先頭からマッチした文字列の末尾までをアペンドし、 カーソルをマッチした文字列の末尾の次の文字に変更する。 従って、appendReplacement() を繰り返すことで マッチした文字列の末尾までを次々にアペンドできる。 最後に appendTail() をコールすることで、 最後にマッチした文字列の次の文字から後ろをアペンドする。