201

HTMLページからタイトルを抽出する正規表現が必要です。現在私はこれを持っています:

title = re.search('<title>.*</title>', html, re.IGNORECASE).group()
if title:
    title = title.replace('<title>', '').replace('</title>', '') 

<title>の内容だけを抽出する正規表現があるので、タグを削除する必要はありませんか?

4

11 に答える 11

318

( )正規表現およびgroup(1)Pythonで使用して、キャプチャされた文字列を取得します(結果が見つからない場合re.searchは返されるため、直接使用しないでください):Nonegroup()

title_search = re.search('<title>(.*)</title>', html, re.IGNORECASE)

if title_search:
    title = title_search.group(1)
于 2009-08-25T10:29:31.147 に答える
43

を開始Python 3.8し、代入式(PEP 572):=演算子)を導入すると、if条件内で直接一致結果を変数としてキャプチャし、条件の本体で再利用することで、KrzysztofKrasońのソリューションを少し改善できることに注意してください。 :

# pattern = '<title>(.*)</title>'
# text = '<title>hello</title>'
if match := re.search(pattern, text, re.IGNORECASE):
  title = match.group(1)
# hello
于 2019-04-27T15:06:30.660 に答える
10

キャプチャグループを使用してみてください。

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
于 2009-08-25T10:30:02.813 に答える
8

美しいスープをお勧めします。Soupは、すべてのhtmlドキュメントを解析するための非常に優れたライブラリです。

soup = BeatifulSoup(html_doc)
titleName = soup.title.name
于 2013-03-01T19:22:25.613 に答える
5
re.search('<title>(.*)</title>', s, re.IGNORECASE).group(1)
于 2009-08-25T10:28:53.737 に答える
4

試す:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
于 2009-08-25T10:28:45.720 に答える
4

これで十分だと思います:

#!python
import re
pattern = re.compile(r'<title>([^<]*)</title>', re.MULTILINE|re.IGNORECASE)
pattern.search(text)

...テキスト(HTML)が「text」という名前の変数にあると仮定します。

これは、HTML TITLEタグ内に合法的に埋め込むことができる他のHTMLタグがなく、そのようなコンテナ/ブロック内に他の<文字を合法的に埋め込む方法がないことも前提としています。

しかし...

PythonでのHTML解析に正規表現を使用しないでください。HTMLパーサーを使用してください!(完全なパーサーを作成する場合を除きます。これは、さまざまなHTML、SGML、およびXMLパーサーが既に標準ライブラリにある場合に、余分で冗長な作業になります)。

「実世界」のタグスープHTML(SGML / XMLバリデーターに準拠していないことが多い)を処理している場合は、BeautifulSoupパッケージを使用してください。(まだ)標準ライブラリにはありませんが、この目的のために広く推奨されています。

もう1つのオプションは次のとおりです。lxml ...適切に構造化された(標準に準拠した)HTML用に記述されています。ただし、BeautifulSoupをパーサーとして使用するようにフォールバックするオプションがあります:ElementSoup

于 2009-08-25T10:35:29.340 に答える
4

提供されたコードは、Exceptions 私が提案するかもしれないものに対応していません

getattr(re.search(r"<title>(.*)</title>", s, re.IGNORECASE), 'groups', lambda:[u""])()[0]

パターンが見つからない場合、または最初に一致した場合、これはデフォルトで空の文字列を返します。

于 2013-10-27T14:07:28.537 に答える
2

KrzysztofKrasońによる現在の投票数の多い回答は、で失敗し<title>a</title><title>b</title>ます。また、行の長さなどの理由で、行の境界を越えるタイトルタグを無視します。最後に、<title >a</title>(有効なHTML:XML / HTMLタグ内の空白)で失敗します。

したがって、私は次の改善を提案します。

import re

def search_title(html):
    m = re.search(r"<title\s*>(.*?)</title\s*>", html, re.IGNORECASE | re.DOTALL)
    return m.group(1) if m else None

テストケース:

print(search_title("<title   >with spaces in tags</title >"))
print(search_title("<title\n>with newline in tags</title\n>"))
print(search_title("<title>first of two titles</title><title>second title</title>"))
print(search_title("<title>with newline\n in title</title\n>"))

出力:

with spaces in tags
with newline in tags
first of two titles
with newline
  in title

最終的に、私はHTMLパーサーを推奨する他の人たちと一緒に行きます-だけでなく、HTMLタグの非標準的な使用を処理するためにも。

于 2020-10-30T08:17:27.643 に答える
1

先読みと後読みの使用を誰も提案しなかった特別な理由はありますか?私はまったく同じことをしようとしてここに来て、うまくいきました(?<=<title>).+(?=<\/title>)。括弧の間の内容にのみ一致するため、グループ全体を実行する必要はありません。

于 2021-05-18T21:48:19.783 に答える
1

一致するものpackage-0.0.1(名前、バージョン)が必要でしたが、などの無効なバージョンを拒否したいと思います0.0.010

regex101の例を参照してください。

import re

RE_IDENTIFIER = re.compile(r'^([a-z]+)-((?:(?:0|[1-9](?:[0-9]+)?)\.){2}(?:0|[1-9](?:[0-9]+)?))$')

example = 'hello-0.0.1'

if match := RE_IDENTIFIER.search(example):
    name, version = match.groups()
    print(f'Name:     {name}')
    print(f'Version:  {version}')
else:
    raise ValueError(f'Invalid identifier {example}')

出力:

Name:     hello
Version:  0.0.1
于 2021-05-20T14:00:38.640 に答える