import re
tag_str = "</li>"
match = re.search(r"</([a-zA-Z0-9-]+)>", tag_str)
if match:
tag_name = match.group(1)
print(tag_name) # 出力: li
上記のpythonのコードで
tag_strがもう少し多くのhtmlの要素の文字列が格納されていて、
特定の要素。たとえばdiv あるいは sectionを探索したいときは
matchの変数のほうは、
match = re.search(r"</(div|section)>", tag_str)
と記述すればいいそうですが、
これだと タグの中に属性名とその値が含まれているときは
マッチしないのではないでしょうか?
特定の属性名の後に、空白が0個以上、そして属性名は
[a-zA-z0-9-]+
それと必ずイコール(=)
そのあとに属性の値[a-zA-z0-9-]+
(ダブルクォーテーション、あるいはシングルクォーテーションで囲まれているでしょうか?)
属性名と値が複数個含まれているタグにマッチするには
どのような正規表現のパターンの記述になるでしょうか?
↓
特定のHTML要素(例: `div` や `section`)が、
属性を持つ場合もマッチさせる正規表現を作成するには、
以下のポイントを考慮する必要があります。
### 要点:
1. タグ名は `<div>` や `<section>` のようにマッチさせる
2. 任意の属性が含まれている場合に対応する
- 属性名: `[a-zA-Z0-9-]+`
- イコール `=`
- 値: `"`または`'`で囲まれた`[a-zA-Z0-9-]+`
3. 属性の個数が 0 以上(属性なしの `<div>` にも対応する)
4. 最後にタグの閉じ `>` を含める
---
### 正規表現:
```python
import re
tag_str = '<div class="container"
id="main-section" data-role="content"></div>'
match
= re.search(r"<(div|section)(\s+[a-zA-Z0-9-]
+=\"[^\"]*\")*\s*>", tag_str)
if match:
tag_name = match.group(1)
print(tag_name) # 出力: div
```
---
### 解説:
- `<(div|section)`
→ `<div>` や `<section>` の開始タグをマッチ
- `(\s+[a-zA-Z0-9-]+=\"[^\"]*\")*`
→ `class="container"` などの属性をマッチ
- `\s+` … 1つ以上の空白(スペースまたはタブ)
- `[a-zA-Z0-9-]+` … 属性名(英数字と`-`を許容)
- `=` … 属性の区切り
- `"[^"]*"` … `" "` で囲まれた属性値
(`[^\"]*` は `"` 以外の文字を許可)
- `*` … 属性は 0 個以上(属性なしにも対応)
- `\s*>`
→ タグの閉じ `>` をマッチ
---
### 追加のポイント
#### 1. シングルクォートにも対応する
もし属性の値が `' '` (シングルクォート) の場合にも
対応するには以下のように修正:
```python
match
= re.search(r"<(div|section)(\s+[a-zA-Z0-9-]
+=(\"[^\"]*\"|'[^']*'))*\s*>", tag_str)
```
- `( \"[^\"]*\" | '[^']*' )` の部分で `" "` か `' '` どちらのパターンも許容
#### 2. 自己閉じタグ `<div />` にも対応する
もし `<div />` のような自己閉じタグにも対応したい場合:
```python
match = re.search(r"<(div|section)(\s+[a-zA-Z0-9-]+=(\"[^\"]*\"|'[^']*'))*\s*/?>", tag_str)
```
- `/?` の追加により、`<div>` や `<section>` だけでなく
`<div />` もマッチ
---
### 実行例:
```python
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*/?>"
for tag_str in test_cases:
match = re.search(pattern, 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
```
---
### まとめ:
- `<div>` や `<section>` をマッチ
- 属性があっても問題なし
- `" "` や `' '` の属性値を認識
- 自己閉じタグ `<div />` にも対応可能
この正規表現を使えば、`div` や `section` だけを確実にマッチできます!
コメント
コメントを投稿