Python正規表現でひらがな・カタカナ一文字を除去する方法

このQ&Aのポイント
  • 正規表現を使用して、テキストデータから「ひらがな一文字」「カタカナ一文字」の単語を除去したい。
  • 現在のプログラムでは、行の先頭や末尾にひらがな・カタカナがある場合、正しく除去できない。
  • スペースを入れることなく、正規表現を使って効果的にひらがな・カタカナ一文字を除去する方法を教えてほしい。
回答を見る
  • ベストアンサー

python 正規表現

http://okwave.jp/qa/q8693280.html 以前したこの質問を参考に正規表現を使ったプログラムを書いているのですが 以下のような3行からなるテキストデータ(例)から「ひらがな一文字」「かたかな一文字」の単語のみを除去したいと思っております。 (例) 単語 あ 語句 みち 空 ジャンプ 無理 ぃ お 暮らし ホーミング 石 防止 ゾ あなた URLの質問を参考に(\bでは除去できなかったので) for line in textfile:  line = re.sub(u'\s[ぁ-ゞ]\s', u' ', line)  line = re.sub(u'\s[ァ-ヾ]\s', u' ', line) としたらうまく「ひらがな一文字」「かたかな一文字」を除去できました。 しかし、次の例のように一つ目の単語にこれらがきた場合手前にスペースがないので除去できません(4行目の「ま」が除去できない) 単語 あ 語句 みち 空 ジャンプ 無理 ぃ お 暮らし ホーミング 石 防止 ゾ あなた ま 空白 みどり だからといって [ぁ-ゞ]\s のようにすると、例えば一行目は「単語 語句 み空 ジャンプ」のように一文字でない単語の最後にひらがな・カタカナがくるとその部分を除去し、後ろの単語と結合してしまうという不具合がおきてしまいます。 扱うデータ的に、行の頭にスペースを入れるということはしたくありません。(はじめに入れて後から消すといっても正規表現に当てはまった行はスペースがなくなり、そうでないところはあるといったバラバラな状況が発生するのでそれもしたくありません) これらをふまえて、うまく「ひらがな一文字」「カタカナ一文字」を除去する方法・正規表現はあるでしょうか。(今書いているプログラムはこのFor文のみなので、別で行が追加される分にはかまいません。) よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.3

\b を回答した者です。日本語は「語」と見なされないようでダメみたいですね。 しょうがないので、  line = re.sub(u'\s[ぁ-ゞァ-ヾ]\s', u' ', line)  line = re.sub(u'\A[ぁ-ゞァ-ヾ]\s', u'', line)  line = re.sub(u'\s[ぁ-ゞァ-ヾ]\Z', u'', line) と行中、行頭、行末と3回に分けて。

qwewqwe
質問者

お礼

再度ありがとうございます!助かります 参考にやってみます

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

せっかくなので、正規表現について勉強しましょう。 正規表現 HOWTO http://docs.python.jp/2/howto/regex.html 7.2. re — 正規表現操作 http://docs.python.jp/2.7/library/re.html \bについては、2つの罠にハマっています。 一つは、上記HOWTOにもあるものです http://docs.python.jp/2/howto/regex.html#more-metacharacters > \b > 単語の境界。(略) > この特別なシーケンスを利用するときには二つの微妙な点を心にとめておく必要があります。 > まずひとつめは Python の文字列リテラルと表現の間の最悪の衝突を引き起すことです。 > Python の文字列リテラルでは \b は ASCII 値8のバックスペース文字です。 > raw string を利用していない場合、Python は \b をバックスペースに変換し、正規表現は期待するものとマッチしなくなります。 もう一つは、reモジュールの説明の方にあります。 > \b > 空文字列とマッチしますが、単語の先頭か末尾の時だけです。 > 単語は英数字あるいは下線文字の並んだものとして定義されています (略) > 英数字であると見なされる文字の正確な集合は、 UNICODE と LOCALE フラグの値に依存することに注意して下さい。 つまり、現状は、ひらがなは「単語の一部ではない」と見做されている状態です。 対策としては ・UNICODEフラグONでcompileしたreのオブジェクトを使う。 コンパイル済みの正規表現オブジェクトの使い方はHOWTOにも書いてあります。 forの外でcompileすると、forの中では、毎回正規表現をコンパイルする必要が無くなり、効率の向上が期待できます。 ・(?u)で、UNICODEフラグを設定する > (?iLmsux) > ( 集合 'i', 'L', 'm', 's', 'u', 'x' から1文字以上) 。 > 文字は、正規表現全体の対応するフラグ (re.I (大文字・小文字を区別しない), re.L (ロケール依存), re.M (MULTILINEモード), re.S (DOTALLモード), re.U (Unicode依存), re.X (冗長) ) を設定します。 あと、\s だと 無理 ぃ お 暮らし ホーミング の「お」にマッチしません。 「お」の前の空白が、「ぃ」の後の空白としてマッチしてしまうため、続きが「お」からになるからです。

qwewqwe
質問者

お礼

ありがとうございました!非常に参考になりました

  • siffon9
  • ベストアンサー率64% (136/211)
回答No.1

行頭の1文字あるいは行末の1文字を削除する正規表現を追加してみては如何でしょうか? line = re.sub(u'^[ぁ-ゞ]\s', u' ', line) line = re.sub(u'\s[ぁ-ゞ]\s', u' ', line) line = re.sub(u'\s[ぁ-ゞ]$', u' ', line)

qwewqwe
質問者

お礼

ありがとうございました!参考にさせていただき勉強してみます

関連するQ&A

  • python 正規表現

    pythonを使用して 単語 あ 語句 みち 空 ジャンプ 無理 ぃ お 暮らし ホーミング 石 防止 ー あなた というような3行からなるテキストデータ(例)を編集したいと思っています ここで ・ひらがな一文字 ・カタカナ一文字 の単語のみ削除しようと思いプログラムにかけると 単語 語句 空 無理 暮 石 防止 となってしまいます プログラムでは以下のようにしております for line in txtfile:  line = re.sub(u'[ぁ-ゞ]', u'', line)  line = re.sub(u'[ァ-ヾ]', u'', line) 本来ほしい結果は 単語 語句 みち 空 ジャンプ 無理 暮らし ホーミング 石 防止 あなた のような結果なのですがこのように他の単語には影響せず一文字のひらがな・かたかなのみを削除するようなコードのアドバイスをいただけないでしょうか? よろしくお願いいたします

  • 正規表現について

    お世話になります。 ●●● ●●● という文字列かどうか判断する正規表現を作成したいです。 条件としては、 ・「文字1 (←全角スペース)文字2」という感じで、文字1と文字2に全角スペースが挟まれている感じで、文字列の先頭にも末尾にも空白文字は入ってはいけない(真ん中に1つのみ) ・文字1と文字2には、数字・空白以外の文字が入る(主に感じ・ひらがな・カタカナが入る)(文字数は一文字以上) といったところです。 自分で作成した正規表現は、 $pattern = '/^([\d\S])+ ([\d\S])+$/'; if( !preg_match($pattern,$chkStr) ) print "マッチしていない"; } なんですが、どうもマッチしてほしい文字にマッチしていないようなのです。 お手数ですがご教授ください。

    • ベストアンサー
    • PHP
  • 日本語の正規化表現

    urizakaです J2SDK1.4から正規表現が標準についたと知り、さっそくカタカナエラーチェックのためのBeanを作ってみたのですが、どんな文字列(カタカナ、英語、ひらがな…etc)と比較させても「False」しか戻ってこないという状態で、うまく行きません。 /** *カタカナエラーチェック:カタカナは使われているかどうか? *@param s 調べる **/ public boolean checkKkana(String s){ Pattern pattern = Pattern.compile("[^アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨワヲン]"); Matcher matcher = pattern.matcher(s); boolean check = matcher.matches(); return check; } } もしかすると、日本語を処理するのには特別な方法が必要なのでしょうか? すみませんが、よろしくお願いします

    • ベストアンサー
    • Java
  • VB2008 正規表現 うまくいきません [ ]?

    VB2008にてプログラムを組んでいます。 RichTextBox に英文を流し込んでありますが、それに対して英単語を検索して、ハイライトするプログラムを組んでいます。 しかし、正規表現の表現方法が悪くうまく検索してくれません。 例えば、RichTextBox には次のような英文があります。 I have seen many chavette. 上記英文に対して、下記のような正規表現で検索しているのですが、 [ -]?have[ s,-]? "have s"がヒットしてしまいます。 その他、chavetteという単語も回避したいのにヒットしてしまいます。 どのように正規表現を訂正すればよいでしょうか。 ================================== 【have の前に"[ -]?"をつけた理由】 "chavette" のような単語を回避し、 "abc-have" のような単語や " have" のような前にスペースのある単語はヒットさせたいからです。 "?"は0か1文字という理由です。 【have の後ろに"[ s,-]?"をつけた理由】 "have-had-had" のような文字列や "haves" のようなsがつく単語や "have," のようなカンマつきの単語や "have " のような後ろにスペースのある単語はヒットさせたいからです。 "?"は0か1文字という理由です。

  • 正規表現について

    正規表現につての質問です。 今テキストファイルに下記のような漢字と数字が並んでいます。 そこから、漢字一文字だけの行を抜き出してきたいのですが、うまくいきません。PerlとCygwinを使用しています。よろしくお願いします。 人584504122 情報542701982 商品510342870 日414551872 方347990908 者347069359 中339925319 表示330177395 的324961911 私323727263 検索291502623 見ル285226619 場合275698771 一256241900 利用253752129 年240881734 時239273060 前228762989 店225241510 登録224560617   ・   ・    ・ プログラム中身 #! /usr/bin/perl -w #テキストから指定した単語などとマッチすると、 #その単語を含んだ文を抜き出してくる。 while(<>){ s/ +//g; s/\s+//g; if(/^([亜-煕]|[一-龠]){1}[0-9]*/){ print; print "\n"; } }

  • 正規表現の置換で、カンマで区切られた語句を""と改行で分ける方法

    正規表現による置換についてお教えください。 Unixのコマンドで置換するときに、sed コマンドを使うと思います。 今、プログラムのソースコードの中に含まれている語句を取得するために、色々いじろうと思っています。 私が最もお聞きしたいのは、正規表現の書き方であることを、まずご理解ください。 ソースコードの中に、 string headline="語句1,語句2,・・・,語句n-1,語句n"; というように、 string headline= で始まっていて、 その後に " "(ダブルクォーテーションの組)で囲まれた部分が1箇所あり、 その部分に、カンマ(,)で区切られた語句がいくつもあるような行があったとき、 その " "の部分を、 "語句1", "語句2", ・・・ "語句n-1", "語句n" のように置換したいのです。 つまり、語句一つ一つをダブルクォーテーションで包んで、1行に語句が1つになるようにしたいのです。 厳密に言えば、stringとheadlineの間などに、タブや空白がいくつあるかわからないという問題なども考える必要があるかもしれません。 とりあえず私が考えたのは、 s/\(string headline="\)\([^,]\)+,\(";\)/\1\2",改行"\3/g です。 s/置換前の文字列のパターン/置換後の文字列のパターン/g となっています。 置換前のパターンで \( \) で囲まれている部分は、置換後のほうで、\1のように参照できます。 ■■でも、私の書いたものって、語句が繰り返し出現することに対応できていないように思われます。■■ 実際に、置換に改行を含めるには、正規表現をファイルの中に書いて、sedの-fオプションで読み込ませることになると思います。 string headline=" " という形をしていないものは、たとえ、" " の中がカンマで区切られていてもそれを分けません。

  • 全角カタカナの正規表現

    if (preg_match('/[ァ-ヶー]+/', $value, $match )) { print ("$value"."はカタカナです。"."($match[0])"."<br />") } else { print ("$value"."はカタカナではない。<br />"); } という感じで全角カタカナにマッチさせる正規表現を使いたいのですが、このやり方だと「全角カタカナを含んでいる…」という表現になってしまいます。ある文字列が「すべて全角カタカナである」という正規表現を考えているのですが、なかなかうまくいきません。逆引きのサンプルなんかでもなかなか見つからなくて困っています。  同様に「すべて平仮名にマッチ!」というのにも応用できると思うのですが、なかなかうまく行きません。  是非、そのやり方やヒントをおしえてください。  マルチバイト対応なので[ぁ-ん]のような形で表記できます。またPerl互換(preg_match)で作っているので、Perlに詳しい方も是非是非おしえてください。

    • ベストアンサー
    • PHP
  • 正規表現についての質問です。

    正規表現につての質問です。 今テキストファイルに下記のような漢字と数字が並んでいます。 そこから、漢字一文字だけの行を抜き出してきたいのですが、うまくいきません。PerlとCygwinを使用しています。よろしくお願いします。 人584504122 情報542701982 商品510342870 日414551872 方347990908 者347069359 中339925319 表示330177395 的324961911 私323727263 検索291502623 見ル285226619 場合275698771 一256241900 利用253752129 年240881734 時239273060 前228762989 店225241510 登録224560617   ・   ・    ・ プログラム中身 #! /usr/bin/perl -w #テキストから指定した単語などとマッチすると、 #その単語を含んだ文を抜き出してくる。 while(<>){ s/ +//g; s/\s+//g; if(/^([亜-煕]|[一-龠]){1}[0-9]*/){ print; print "\n"; } }

  • 正規表現検索

    Javaのソースコード内から特定の単語を検索したいのですが、 このとき、以下の条件があります。 (1)ブロックコメント内を無視する (2)行コメント内を無視する (3)変数文字列内を無視する 01 /* 02 * ここの abc はブロックコメント内なので無視する 03 * 04 */ 05 public class Foo() { 06  private int abc = 0; 07 08  public Foo() { 09   // 行コメント内なのでここの abc を無視 10   abc = 1; 11   String s = "変数文字列内の abc これも無視"; 12  } 13 14  public String get() { 15   return " 1'23\" abc " + abc; // この場合後ろの abc のみヒット 16  } 17 } 例えば、上記のテキストで abc を検索したとき、 6、10と15行目の後ろの3箇所のみヒットさせたいのですが、 これはどのように正規表現で記述すればよいのでしょうか。 /* で始まり、*/ が記述されるまでがブロックコメントです。 // があったら、その行末までが行コメントです。 " で囲まれた中が変数文字列です。文字列内の \" は無視します。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Rubyの変数を含んだ正規表現について

    下のように正規表現でlineと 1=,2=などから始まる行を抽出する プログラムですが、どうやら正規表現の左辺(//の中身) には変数は使えないようです。iが文字として 認識されているようです。 解決策を教えてください。 while line = io.gets  20.times{ |i|   if /^i=(.*)/ =~ line   p $1  } end

専門家に質問してみよう