python_正規表現_htmlの要素のマッチするためのパターンの変数、 pattern_all

 

import re


test_cases = [


    "<div></div>",


    "<section id='content'></section>",


    '<div class="box" id="main" data-value="123"></div>',


    "<div />",


    "<section disabled></section>",  # 属性値なし


]


#pattern = r"<(div|section)(\s+[a-zA-Z0-9-]+=(\"[^\"]*\"|'[^']*'))*\s*/?>"


pattern01 = r"<(div|section)(\s+[a-zA-Z0-9-]+\s?=\s?(\"[^\"]*\"|'[^']*'))*\s*/?>"



for tag_str in test_cases:


    match = re.search(pattern, tag_str)


    if match:


        print(f"Matched tag: {match.group(1)}")


上記のpythonのコードだと、

変数 matchはhtmlの要素のうち div と section には

マッチすると思いますが、


他のhtml要素にもマッチするようにするには、

下記のようなパターンで動作するでしょうか?


pattern02 = r"<([a-zA-Z0-9-_]+\s+[a-zA-Z0-9-]+\s?=\s?(\"[^\"]*\"|'[^']*'))*\s*/?>"



`pattern02` の正規表現にはいくつか問題があります。

特に、次のような誤りがあります:


1. 

`<([a-zA-Z0-9-_]+\s+[a-zA-Z0-9-]+\s?=\s?(\"[^\"]*\"|'[^']*'))*\s*/?>`


   - `<([a-zA-Z0-9-_]+...` の部分は、タグ名の部分ですが、

属性(`id=...` など)を強制するようになってしまい、

**属性なしのタグにマッチしなくなる**。

   - `[_]` を含めていますが、HTML のタグ名には

`_`(アンダースコア)は通常含まれません。


---


### **修正後のパターン**


すべての HTML タグ

(`div`, `section`, `span`, `p`, `a`, など)にマッチし、

属性があってもなくても動作するようにする場合、

次のようなパターンが適切です。


```python


pattern_all = r"<([a-zA-Z0-9-]+)(\s+[a-zA-Z0-9-]+\s?=\s?(\"[^\"]*\"|'[^']*'))*\s*/?>"


```


**修正ポイント:**


1. **`([a-zA-Z0-9-]+)`** → タグ名をキャプチャ


   - タグ名は英数字 (`a-zA-Z0-9`) と 

`-`(ハイフン)を含む(カスタムタグ対応)。

   - `_`(アンダースコア)は通常HTMLタグ名には含まれないので除外。

   

   

2. **`(\s+[a-zA-Z0-9-]+\s?=\s?(\"[^\"]*\"|'[^']*'))*`**


→ 属性を表す部分


   - `\s+`(スペース)が続いた場合に属性(`id="..."` など)をマッチ

   

   - 属性は `"..."` または `'...'` で囲まれている

   

   

3. **`/?\s*>`** → `/>`(セルフクローズタグ) 

または `>`(通常タグ) に対応



---


### **テストコード**


```python


import re


test_cases = [


    "<div></div>",

    "<section id='content'></section>",

    '<div class="box" id="main" data-value="123"></div>',

    "<div />",

    "<section disabled></section>",  # 属性値なし

    "<p>Paragraph</p>",

    "<a href='https://example.com'>Link</a>",

# セルフクローズ

    "<br />",  

# カスタムタグ

    "<custom-tag data-x='123'></custom-tag>",  

]


pattern_all = r"<([a-zA-Z0-9-]+)(\s+[a-zA-Z0-9-]+\s?=\s?(\"[^\"]*\"|'[^']*'))*\s*/?>"


for tag_str in test_cases:

    match = re.search(pattern_all, tag_str)

    if match:

        print(f"Matched tag: {match.group(1)}")

```


---


### **出力結果**


```


Matched tag: div

Matched tag: section

Matched tag: div

Matched tag: div

Matched tag: section

Matched tag: p

Matched tag: a

Matched tag: br

Matched tag: custom-tag


```


**すべての HTML タグ

(div, section, p, a, br, custom-tag など)にマッチ!** 🎉





コメント