次の正規表現を検討してください。
<a href(="(?:/user)?/([^"]+))">
私が望むのは、2番目のキャプチャグループにすべての/のみの数字がある場合、この正規表現は一致しないはずです。例:
<a href="/user/15594243">
#this should not match
そのための解決策はありますか?正規表現ソリューションのみが必要です。さらにPythonコードを使用してこれを達成できることを知っています。
すべての数値に対する否定先読みアサーションと引用符だけが必要だと思います。」
user_re = re.compile('<a href(="/(?!(?:user/)?[0-9]+").+)"')
In [74]: [(url,user_re.match(url) and user_re.match(url).group(1)) for url in
['<a href="/user/15594243">',
'<a href="/user/15594243_">',
'<a href="/user/user15594243">',
'<a href="/user/1">',
'<a href="/user/15594243/add">',
'<a href="/item/15594243">',
'<a href="/a"',
'<a href="/15594243">']]
Out[74]:
[('<a href="/user/15594243">', None),
('<a href="/user/15594243_">', '="/user/15594243_'),
('<a href="/user/user15594243">', '="/user/user15594243'),
('<a href="/user/1">', None),
('<a href="/user/15594243/add">', '="/user/15594243/add'),
('<a href="/item/15594243">', '="/item/15594243'),
('<a href="/a"', '="/a'),
('<a href="/15594243">', None)]
編集:最後の編集で正規表現を2回実行することは知っていますが、それは表示目的のためだけです。
どうですか
<a href(="(?:/user)?/([^"/]*?[^0-9"/][^"/]*?))">
? / を含める必要があります。そうでない場合、/user は省略可能であるため省略され、user/ は非数値として取り込まれます...
これを 2 番目のキャプチャ グループに使用します。
\d*[a-zA-Z]+[a-zA-Z0-9]*
これにより、必要に応じて数字で開始し、少なくとも 1 つのアルファベットを要求し、必要に応じて英数字を続けることができます。
アサーションを使用できます。固定幅が必要な後読みアサーションは機能しないので、先読みを使用しましょう。
reg = re.compile("<a href=\"(?:/user)?/(?![0-9]+)([^\"/]+)\">")
これは機能します。しかし、この正規表現はこれらの URL を無効にします: /user/test/u345
, /user/t/user
(スラッシュは使用できません)。これは、あなたの部分がオプションであるためです: ( )/user
の仮定なしで、すべてを消費します ( )[^"/]
[^"]
/user/45
これで十分です。次のものに置き換えます([^"]+)
。
([^"]*?[^0-9"][^"]*?)
編集:Pythonが大文字のQを持つ趣のあるものでない限り、私は本当に何が間違っているのかわかりません。JavaScriptコンソールからこれは機能します:
>>> 'user/user1234"'.match(/\/([^"]*?[^0-9"][^"]*?)"/);
Array ["/user1234"", "user1234"]
>>> 'user/1234"'.match(/\/([^"]*?[^0-9"][^"]*?)"/);
null
それで、これはPythonには当てはまらないと言っていますか?なんで?
edit2:ああ、オプション/user
は結果をファウルします....これはそれを防ぎます:
<a href(="(?:/user)?/(?!user/)([^"]*?[^0-9"][^"]*?))">