java - 特定の属性なしでhtmlタグに一致する正規表現
4 に答える
説明
のような正規表現には注意してください。これらは、やなど<a[^>]*
で始まる他の有効な html タグとも一致します。また、単に文字列の存在を探すだけでは十分ではありません。その文字列は、別の属性の値や など、または別の属性の一部の中にある可能性があるためです。a
<abbr>
<address>
href
<a class="thishrefstuff"...
<a hreflang="en"...
この式は次のようになります。
- 属性を含まないすべてのアンカー タグに一致し
<a
ます。</a>
href
- タグ名が強制され、
a
単に文字で始まるタグではありませa
ん<address>
- validや made up の
href
ように、属性の名前に部分文字列が埋め込まれている属性も無視します。hreflang='en'
Attributehref="some value"
- 次のような適切にフォーマットされたすべての属性の値部分内のすべての文字を無視します
bogus='href=""'
<a(?=\s|>)(?!(?:[^>=]|=(['"])(?:(?!\1).)*\1)*?\shref=['"])[^>]*>.*?<\/a>
エキスパンド
<a(?=\s|>)
開始タグに一致し、タグ名の後の次がスペースまたは閉じ括弧のいずれかであることを確認します。これにより、名前が他のa
ものではなく強制的に指定されます(?!
このタグに href が見つかった場合、このタイプのタグは探しているタグではありません。(?:
非キャプチャ グループを開始して、タグ内のすべての文字を移動します[^>=]
正規表現エンジンがタグを離れることを防ぐすべての非タグ終了文字と、エンジンが盲目的にすべての文字の一致を続行することを防ぐ非等号に一致します|
また=(['"])
等号の後に開始二重引用符または単一引用符が続くものと一致します。見積もりはグループ 2 に取り込まれ、後で正しくペアリングできるようになります(?:(?!\1).)*
開始引用符に一致する終了引用符以外のすべての文字に一致\1
正しい終了引用符に一致する)*?
非キャプチャグループを閉じて、必要なだけ繰り返します。\shref=['"]
目的の href 属性に一致します。\s
and=["']
は、属性名が単に href であることを保証します)
否定的な先読みを閉じる
[^>]*>.*?<\/a>
最初から最後まで文字列全体に一致する
Java コード例:
入力テキスト
<abbr>RADIO</abbr> text <a class="aClass" href="#">link1</a> text <a bogus='href=""' class="aClass" target="_blank">link2</a> text
コード
これを置換関数で使用して非 href-anchor タグを削除する場合は、すべての一致を何も置き換えないでください。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Module1{
public static void main(String[] asd){
String sourcestring = "source string to match with pattern";
Pattern re = Pattern.compile("<a(?=\\s|>)(?!(?:[^>=]|=(['\"])(?:(?!\\1).)*\\1)*?\\shref=['\"])[^>]*>.*?<\\/a>
",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
Matcher m = re.matcher(sourcestring);
int mIdx = 0;
while (m.find()){
for( int groupIdx = 0; groupIdx < m.groupCount()+1; groupIdx++ ){
System.out.println( "[" + mIdx + "][" + groupIdx + "] = " + m.group(groupIdx));
}
mIdx++;
}
}
}
マッチ
$matches Array:
(
[0] => Array
(
[0] => <a bogus='href=""' class="aClass" target="_blank">link2</a>
)
[1] => Array
(
[0] =>
)
)
正規表現で行う必要があるのは奇妙だと思いますが、否定先読みを使用できます。
<a(?![^>]+href).*?>(.*?)</a>
私はJavaの専門家ではありませんが、次のようなことを試すことができます:
String regex = new String("(?i)<a(?>[^h>]++|(?<! )h++|h++(?!ref\\s*+=))*>((?>[^<]++|<(?!/a>))*)</a>");
String replacement = new String("$1");
str.replaceAll(regex,replacement);