質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

解決済

1回答

7998閲覧

【Python 2.7.10】正規表現でURLを取得したい

nnahito

総合スコア2004

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2016/09/22 13:50

編集2016/10/05 05:57

質問概要

文章中に含まれるURLを、正規表現で全て取得したい

質問概要

文章中に含まれるURLを、正規表現で全て取得したいと考えています。
その上で、以下のコードをサンプルとして書いてみました。

lang

1#!/usr/bin/env python 2# -*- coding: utf8 -*- 3 4import re 5 6pattern = u"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?" 7text = "aaaaahttp://www.google.com/\naaaa" 8matchOB = re.search( pattern , text) 9 10print matchOB.group(0)

たったこれだけなのですが、以下のようなエラーが出ます。
pattern = r"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"としてもだめでした。(u"〜"→r"〜")

lang

1Traceback (most recent call last): 2 File "test.py", line 11, in <module> 3 matchOB = re.search( unicode(pattern, 'utf-8') , text) 4TypeError: decoding Unicode is not supported

試しに、

lang

1#!/usr/bin/env python 2# -*- coding: utf8 -*- 3 4import re 5 6 7pattern = "a" 8 9text = "aaaaahttp://www.google.com/\naaaa" 10matchOB = re.search( pattern , text) 11 12print matchOB.group(0)

とすると、

lang

1$ python test.py 2a

のように、しっかり返ってきました。

これは何が原因なのでしょうか?
ご存じの方がいらっしゃいましたら、ご教示願います。

環境

Python 2.7.10
MacOS X 10.10.5(Yosemite)

修正依頼からの修正

コード

lang

1#!/usr/bin/env python 2# -*- coding: utf8 -*- 3 4import re 5 6text = u'hogehoge http://www.example.com/ mugemuge' 7 8 9# URLを抜き出し 10urls = re.search(u'http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?', text) 11 12for i in urls: 13 print i

エラー

Traceback (most recent call last): File "test.py", line 10, in <module> urls = re.search(u'http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?', text) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 146, in search return _compile(pattern, flags).search(string) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 251, in _compile raise error, v # invalid expression sre_constants.error: bad character range

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2016/10/03 09:39

エラーメッセージと、それが出力されたというソースコードが対応していません。ソースコードは変更があるごとに示して、それぞれでどのような結果になったかを示してください。また、エラーのときに結果として表示されたもの (スタックトレース) は省略せずに全て示してください。
nnahito

2016/10/05 05:57

情報の修正を追記させていただきました
guest

回答1

0

ベストアンサー

修正後のほうのエラーについて回答します。

スタックトレースを見るに、正規表現のパターンをコンパイルする中で例外が発生しています。ですので正規表現の書きかたに問題があると考えられます。そして、根本的なエラーメッセージは「bad character range」(直訳:「よくない文字の範囲」) だと言っていますから、文字の範囲の書きかたに問題があります。

正規表現のどこに問題があるか調べるには、部分表現を取り出してみればいいです。ご質問の正規表現には、文字の範囲を表す部分表現が2種類含まれます。

  • [\w-]
  • [\w- ./?%&=]

これらの表現をre.search()に与えてみると、「bad character range」となるのは後者であることが分かります。

そこで、『Python標準ライブラリリファレンス』の「7.2. re — 正規表現操作」「7.2.1. 正規表現のシンタクス」で、文字の範囲についての正規表現の書きかたを確かめます。下記は関係する部分の引用です。


[]
文字の集合を指定するのに使用します。集合には以下のものが指定できます:

  • 個別に指定できる文字。[amk]'a', 'm', 'k' とマッチします。
  • 連続した文字の範囲を、先頭と最後の2文字とその間に '-' を挟んだ形で指定できます。[a-z] はすべての小文字の ASCII 文字とマッチします。 [0-5][0-9]00 から 59 までの、すべての 2 桁の数字とマッチします。[0-9A-Fa-f] は任意の 16 進数の数字とマッチします。 - が、エスケープされた場合 (例: [a\-z])、あるいは先頭か末尾に置かれた場合 (例: [a-])、リテラル '-' とマッチします。

(後略)


上のふたつの部分表現のうち前者は、-が「末尾に置かれた場合」ですから、「単語文字または-」にマッチする正しい正規表現です。

ところが後者は、\w- ……あえて言うなら「単語文字から空白までの間の文字」という、意味不明なものを含んでいます。これが「よくない文字の範囲」だというわけです。-を文字の範囲に含めたいのであれば、[-\w ./?%&=]のように-を先頭に置けばいいでしょう。

注記

正規表現にUnicode文字列を使っている場合とバイト列を使っている場合とでは、\wがマッチする範囲が異なります。ご自分の目的通りの範囲でマッチさせるようにする方法については、上記のリファレンスを参照してください。

投稿2016/10/05 07:56

ikedas

総合スコア4335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2016/10/09 11:48

ご回答ありがとうございます。 正規表現は苦手で、コピペで動かしており、実はあまり分かっておりません。。。 いただきました情報をもとに、修正していきたいと思います。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問