• ベストアンサー

文字数の多い単語だけ抽出(多言語テキスト)

英・仏・独語の多数のテキストファイルから12文字以上の単語だけ抽出したいのですが効率のよい方法はないでしょうか。 英語だけならテキストエディタの正規表現を使ったgrepで \w{12,} で12文字以上の単語を含む行を検索したうえで、\w{1,11} を空白と置換して削除してしまえばいいのですが(一緒に表示させるフルパスは別途消す必要がありますが)、仏・独語となるとイロイロ問題が出てきます。 例えば、仏語では a'bc'def のようなパターンの単語があります。これを単に検索するだけなら \w'\w+'*\w* で検索できますが、12文字以上と指定する方法がわかりません(アポストロフィがひとつだけなら \w'\w{10,} で12文字以上ということになるのですが…)。 そこで質問なのですが: 1. 上記の仏語のようにアポストロフィを2つ含む12文字以上の単語を抽出するにはどうしたらいいでしょうか。 2. そもそも12文字以上の単語を含む行をgrepしたうえで、11文字以下の単語を消去したりせずに、最初から12文字以上の単語だけを抽出する方法はないのでしょうか。 できれば、フリーウェなどを導入せずにテキストエディタやOffice系アプリなどだけで対処したいと思います。VBSでもOKですが、その場合は、初歩的なことしかわかりませんので、アドヴァイスというより丸投げしてしまうことになります。 どうかよろしくご助言をお願いします

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

  • ベストアンサー
  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.7

No.2です。 No.5さん、指摘ありがとうございます。 処理系によっては\wがLocaleに応じて文字集合を変える場合も あることは知りませんでした。 質問者さんの疑問についてですが、まず > [A-Za-z']{12,} でgrepすると、アポストロフィが1つものには > ヒットしても、2つの場合はダメなようです。 という点については、やはり辻褄が合いません。 もしかするとアポストロフィが1個の場合と2個の場合で 文字コードが微妙に違っているという可能性はないでしょうか? 通常アポストロフィは、シングルクオートでもある0x27が 使われると思うのですが、以下のURLのように0x2019が使われる 場合もあるようです。 http://dslabo.blog4.fc2.com/blog-entry-1323.html また、これ以外にもアポストロフィとして使えそうな よく似た字体はたくさんあるので、問題の単語の アポストロフィに使われている文字コードを一度 きちんと調べたほうがよいのではないかと思います。 それで、#2の回答のVBScriptコードですが、 質問者さんの検索対象ファイルはUTF-8で書かれていて、 検索対象文字もLatin特殊文字をunicodeで指定する 必要があるということがわかりましたので、 以下のように修正しました。 ------------------------------------------------- inFilename = "d:\test.txt" outFilename = "d:\test2.txt" adReadLine = -2 adWriteLine = 1 adSaveCreateOverWrite = 2 Set inFile = CreateObject("ADODB.Stream") inFile.charset = "UTF-8" inFile.Open inFile.LoadFromFile inFilename Set outFile = CreateObject("ADODB.Stream") outFile.charset = "UTF-8" outFile.Open Set regEx = New RegExp regEx.Pattern = "[A-Za-z'\u00c4★]{12,}" regEx.Global = True Do Until inFile.eos checkLine = inFile.ReadText(adReadLine) Set Matches = regEx.Execute(checkLine) For Each Match in Matches outFile.WriteText Match.Value,adWriteLine Next Loop outFile.SaveToFile outFilename,adSaveCreateOverWrite inFile.Close outFile.Close ------------------------------------------------- ★印のところの\u00c4は、Aウムラウトの文字コード(unicode)です。 これで12文字以上の単語(複数の「'」またはAウムラウトありもOK)を 検索できることを確認しました。 ここに、さらに対象文字コードを追加指定すれば、 意図した抽出ができそうに思います。 また、このVBscriptファイルをUTF-16形式で保存すれば、 ★のところには、\u00c4でなく、実際のAウムラウト文字を 記述できます。

Kazu_creator
質問者

補足

大変ご丁寧にご回答くださり、まことにありがとうございました。 アポストロフィとシングルクオートの件については、週明けに出社し次第確認してみたいと思います。 最後に一つだけ甘えさせていただければ、上記のVBSをフォルダ内のファイルを一括処理できるように変更できるでしょうか。 以前、既存のVBSを自分のタスクに合うようにカスタマイズしようと(WEB上のTipsやmsdnのサイトを参照しつつ)トライしたことがあるのですが、動かなかったり不具合が発生したりすることが多く、挫折してしまった経験があります。 いずれは、ちゃんと勉強したいと思いますが、今回はご教示いただけると助かります。 お手数でなければ、よろしくお願いします。

その他の回答 (7)

  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.8

No.2です。 > 最後に一つだけ甘えさせていただければ、上記のVBSをフォルダ内のファイルを > 一括処理できるように変更できるでしょうか。 一括処理といっても、 ・複数ファイルの検索結果は、1ファイルにまとめて出力か? 別々のファイルに出力か?画面に表示するだけでもよいか? ・フォルダ内のサブフォルダも再帰的に処理するか? といったような要件を確認し、それにあった機能を作る 必要があります。 すみませんが、検索ツールの作成を丸抱えしたつもりはありませんので、 アドバイスだけ返信します。 (案1) http://itpro.nikkeibp.co.jp/article/COLUMN/20060120/227640/ の「grepを実行するプログラムのソースコード(VBScript)」 を参考にし、その中の If Y>0 Then ~ End If の間に今回のコードを組み込む。 (案2) http://www.atmarkit.co.jp/fwin2k/operation/wsh04/wsh04_02.html を参考にして、WScript.Argumentsを使って入力ファイル名、出力ファイル名を コマンドパラメータで指定できるよう改造する。 それができたら、検索したいファイルを1個づつ指定してコマンド実行する形で、 全ファイルを処理するバッチファイルを作成する。

Kazu_creator
質問者

お礼

ご助言ありがとうございます。 今回はマニュアル作業でタスクをこなしてしまいましたので、今後の勉強の参考にさせていただきます。 テキスト処理が多いので perl もいいかなと思い、入門書を買ってきました。(VBSの入門書ってあまりないんですね…プログラミング経験者にとっては、無料の解説サイトで十分なんでしょうね)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.6

#4の置換操作で思い通りの結果が得られないというのは、EmEditor の問題ではなくて 質問者さんのオペレーションの問題ですね。 基本的に正規表現はできるだけ長い範囲にマッチしようとするので、 .*\w{12,} のように書くと、前の .* が予想以上のところまで飲み込んでマッチしてしまいます。 ところでUnicodeのコードポイントを使っての文字指定はやはり秀丸でできるようです。 ドイツ語とフランス語のアルファベットの実体参照マクロ - suneoHairWax http://d.hatena.ne.jp/hidex7777/20051019/p1 ////ドイツ語とフランス語でよく使うアルファベットを実体参照に変換 //aウムラウト replaceallfast "\u00E4" , "ä" , casesense; //oウムラウト replaceallfast "\u00F6" , "ö" , casesense; //uウムラウト replaceallfast "\u00FC" , "ü" , casesense; //Aウムラウト replaceallfast "\u00C4" , "Ä" , casesense; //Oウムラウト replaceallfast "\u00D6" , "Ö" , casesense; //Uウムラウト replaceallfast "\u00DC" , "Ü" , casesense; //エスツェト replaceallfast "\u00DF" , "ß" , casesense; //aアクサングラーヴ replaceallfast "\u00E0" , "à" , casesense; //aアクサンシルコンフレクス replaceallfast "\u00E2" , "â" , casesense; //eアクサンテギュ 以下略

Kazu_creator
質問者

お礼

秀丸の仕様を確認していただきありがとうございます。 上記のユニコードのリストを見ていたら、やはり範囲指定できそうな気がしてきました。 今回は面倒な手順を踏んで土臭くタスクをこなしてしまいましたが、週明けに今後に向けてスマートな方法を考えてみたいと思います。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

> a'bc'def これ、実際に a ' b c ' d e f と並んでいるテキストなんでしょうか? それとも本当はアクセント記号つきの文字で一文字なんだけど便宜上アポストロフィを 直後につけて表現しているのでしょうか? \w は明確に何かの規格で決まっているものではないので、使っている エディターだとかスクリプティング言語によって違いがあったりします。 たとえば locale という環境設定を参照し、それによって \w があらわす 文字集合が変わるというのもよくあります。 ですから#2の方の >英文字(A~Z,a~z)または「_」(アンダーパー)文字を意味します。 というのはあまり正確ではありませんし、EmEditor の仕様がアクセント記号つきの文字も 含むものなのかもしれません。 秀丸の仕様がはっきりとわからなかったのですが > 現在、再度秀丸で文字コード範囲を指定した検索にトライしているのですが、[\x0x00010000-\x0x0010FFFF] > や [\x0x0080-\x0x07FF] でも上記のような独語文字にヒットしません。 秀丸エディタを使いこなす ―正規表現―エスケープシーケンス―― http://www.shuiren.org/chuden/teach/hidemaru/seiki/01.htm に >文字コード番号(Shift-JISのコードポイント)を指定する正規表現です。 という説明文がありましたので、ひょっとしたらUnicode やlatin-1の コードで指定するというのはできないのかもしれません。 これまた環境によるのですが、Unicode でのコード番号を指定するために \uXXXX という表記を許すものがあります。 秀丸エディタで使えるかはわかりませんけど。 話を戻して、本当にアポストロフィが使われているのなら [A-Za-z']{12,} でいけそうな気がします。が、ウムラウトなんかはどう表現されるんでしょう?

Kazu_creator
質問者

補足

エディタの仕様などについて詳しく説明していただき、ありがとうございます。大変勉強になりました。 >これ、実際に a ' b c ' d e f と並んでいるテキストなんでしょうか? はい、アクセントとは別に、実際にそのようなパターンの単語があります。 [A-Za-z']{12,} でgrepすると、アポストロフィが1つものにはヒットしても、2つの場合はダメなようです。 また、アクセントの付いたものや、その他フラン語特有の文字などにもヒットしないようです。 結局、EmEditorで、\w'\w+'*\w* という条件で検索しています(その上で、.{1,11} にヒットするものを削除)。 その後さらに \w{12,}でgrepして、11文字以下の単語、記号の類、アンダーバーでつながったストリングID、grepに付き物のフルパスなどなどを削除していきます(+削除の過程でできた余分な改行も削除)。 なかなか楽はできませんね。 >ウムラウトなんかはどう表現されるんでしょう? こういう資料も見つけましたが、秀丸ではうまく指定できませんでした。 http://www.unicode.org/charts/PDF/U0080.pdf

回答No.4

半角カナが全角に変換されてしまいました。 [a-zA-Z'\-ア-ン] ・・・このアとンは半角カナです。

Kazu_creator
質問者

補足

[a-zA-Z'\-ア-ン] (アとンは半角カナ)で試してみましたがダメでした。 ところで EmEditor で、 検索文字列: .*(\w{12,}).* 置換文字列: \1 で置換してみたところ、一見うまく12文字以下の単語を削除(つまり、12文字以上の単語のみ抽出)できたように思えたのですが、何故か ・12文字以上ではなく、12文字の単語のみ抽出される ・ところどころ、抽出漏れがあってセンテンスの一部が残る などの問題が発生しています。 これは、バグなのでしょうか(EmEditor ver.9.03)? それとも設定か何かの問題なのでしょうか?? この件についても判る方がいらしたら、ご助言お願いします。

回答No.3

one-year-old boyは単語として扱われますか? [a-zA-Z'\-ア-ン]はどうでしょうか。 UTF-8なのかLaten-1かで違うと思いますが。

Kazu_creator
質問者

補足

書き忘れていましたが、UTF-8(BOMなし)です。 まずは、上記の条件で試してみます。

  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.2

1. 「\w」は、英単語を表すものではありません。 英文字(A~Z,a~z)または「_」(アンダーパー)文字を意味します。 したがって、「abc_def」といったものにもマッチします。 また、「can't」「I'm」といった1文字アポストロフィ単語には マッチしません。 仏語はよく知らないのですが、英語、仏語いずれにしても、 英文字(A~Z,a~z)または「'」文字が12個以上連続している文字列を 検索対象とすればよいのだと思うので、 \wの替わりに[A-Za-z']を使って、 [A-Za-z']{12,}という感じで検索できそうに思います。 (参考) http://msdn.microsoft.com/ja-jp/library/cc427970.aspx 2. VBScriptで、正規表現にマッチした文字を別ファイルに書き出す処理を 作れば実現できると思います。 以下のコーディングを参考にいろいろ改造してみてください。 ------------------------------------------------------ Set fso = CreateObject("Scripting.FileSystemObject") Set inFile = fso.OpenTextFile("d:\test.txt") Set outFile = fso.CreateTextFile("d:\test2.txt") Set regEx = New RegExp regEx.Pattern = "[A-Za-z']{12,}" regEx.Global = True Do Until inFile.AtEndOfStream checkLine = inFile.ReadLine Set Matches = regEx.Execute(checkLine) For Each Match in Matches outFile.WriteLine Match.Value Next Loop inFile.Close outFile.Close ------------------------------------------------------

Kazu_creator
質問者

補足

ご丁寧に説明いただき誠にありがとうございます。 実は、秀丸では \w が使えないため [a-zA-Z] で検索したところ、独語の ä や ß などがヒットしないために、EmEditorで \w を使用した手法に切り替えたという経緯があります(なぜか\wならOKです)。 現在、再度秀丸で文字コード範囲を指定した検索にトライしているのですが、[\x0x00010000-\x0x0010FFFF] や [\x0x0080-\x0x07FF] でも上記のような独語文字にヒットしません。 ヨーロッパ言語文字にヒットする文字コード範囲などご存じないでしょうか。

noname#182251
noname#182251
回答No.1

ながらく縁がない「プログラミング言語AWK」にそんなのがあったと、久しぶりに本を開いてみたら、P.164に「単語の数え上げ」と云うのがありました。要するに連想配列が扱える言語ならどれでも良さそうです。今時ならばpearlかrubyなんでしょうか。「12文字以上の単語」と云う制限もさほど難しくはないと思います。

関連するQ&A

  • 英・仏・独語で12文字以上の単語を抽出

    英・仏・独語の多数のテキストファイルから12文字以上の単語だけ抽出したいのですが効率のよい方法はないでしょうか。 英語だけならテキストエディタの正規表現を使ったgrepで \w{12,} で12文字以上の単語を含む行を検索したうえで、\w{1,11} を空白と置換して削除してしまえばいいのですが(一緒に表示させるフルパスは別途消す必要がありますが)、仏・独語となるとイロイロ問題が出てきます。 例えば、仏語では a'bc'def のようなパターンの単語があります。これを単に検索するだけなら \w'\w+'*\w* で検索できますが、12文字以上と指定する方法がわかりません(アポストロフィがひとつだけなら \w'\w{10,} で12文字以上ということになるのですが…)。 そこで質問なのですが: 1. 上記の仏語のようにアポストロフィを2つ含む12文字以上の単語を抽出するにはどうしたらいいでしょうか。 2. そもそも12文字以上の単語を含む行をgrepしたうえで、11文字以下の単語を消去したりせずに、最初から12文字以上の単語だけを抽出する方法はないのでしょうか。 できれば、フリーウェなどを導入せずにテキストエディタやOffice系アプリなどだけで対処したいと思います。VBSでもOKですが、その場合は、初歩的なことしかわかりませんので、アドヴァイスというより丸投げしてしまうことになります。 どうかよろしくご助言をお願いします。

  • 単語を抽出する正規表現

    単語を抽出する正規表現を教えてください。grepを使うと、「○○を含む行」がすべて抽出されますが、下記のように単語だけを抽出したいのですが、どうすればいいかご存知の方がいらっしゃいましたら、教えてください。 --- ABC DEF GHIJ AB CDEF GHIJK ABCDE FGH I JKL 上記からGH始まりの単語だけを抽出したいです。 1行目と2行目のGHIJとGHIJKの2つだけが結果として欲しいです。1行目と2行目全体が出てくるのではなくて。 Windowsでは、エディタは秀丸を使ってます。 Windowsで不可能なら、UNIX上で実施することも考えていますが、Windowsのエディタ上で実行できる正規表現の文などありましたら教えてください。

  • grepで全角文字の行を抽出

    grepの検索でテキスト内のひとつでも全角文字がある行を 抽出したいと思ってます。1つの方法は見つかったのですが、 時たまバグがあるそうですので、 他の方法を探そうと思ってます。 わかっている方法は、以下のとおりです。 > grep -n '.*[^ -~。-゜].*' test_data.txt よろしくお願いします。

  • テキストエディタで4桁の数字のみを抽出

    以下の条件でお願い致します。 【条件】 テキストエディタのgrep機能,置換機能のみで実現したい 【質問】 4桁の数字のみを抽出するにはどういった方法があるでしょうか? (該当行1行まるごとではなく「数字4文字」のみ) つまり株式の証券コードのみを残したいと言うことです。 お手数をおかけ致します。よろしくお願い致します。

  • ある文字列が含まれた行だけをテキストから抽出→結果を別のテキストに出力

    ある文字列が含まれた行だけをテキストから抽出→結果を別のテキストに出力したいです。 そのために何かいいソフトウェア、または方法は無いでしょうか? これまでは下記サイトを参考に秀丸エディタの検索&glep機能を使ってやってみたのですが、 抽出したい文字列の数が多く手動でやるのに限界を感じたので質問させていただきました。 http://hechimahige.blog71.fc2.com/blog-entry-4.html 秀丸エディタのマクロでも構いません。 よろしくお願いします。

  • 特定文字の右側を抽出する方法(関数など)

    数が多いので、Excelやテキストエディタなどを使用して、特定文字の右側すべてや右側3文字などを抽出する方法を教えてください。 @以降の文字を抽出したいときなど 1行目 1345@678 2行目 1346@834 3行目 134@3464

  • テキスト内の重複文字検索

    テキスト内の重複文字列を探す方法が分かりません。 たとえば、テキストに数行のテキストがあったとします。このとき、2つ以上使われている単語を検索したいです。(できれば、使われている回数も。) よろしくお願いします。

  • テキストから特定の文字列をすべて抽出する方法

    例えば、「今年のホワイトデーにはお菓子の詰合せを贈ろうと思う。」というテキストファイルがあり、このテキストの『ホワイトデー』と『お菓子』という文字列を抽出し、その文字列に対して外部リンクを設定してページに表示させる場合の処理について、教えていただきたいです。 まず目的の文字列の前後には<w1>~<w2>という文字を付けておき、 文字列中から<w1>~<w2>を検索してその値を返そうとしています。 $str="今年のホワイトデーにはお菓子の詰合せを贈ろうと思う。"; preg_match('/<w1>(.*?)<w2>/is', $str, $keyword); この処理でいけば、マッチした文字列が$keywordに代入されます。 しかし、テキストに2つ以上の<w1>~<w2>がある場合、 そのすべてを抽出することができません。 プログラミング(php)は始めてまだ半年ぐらいなので、まだまだ初歩のレベルです。 どなたかこの抽出処理の部分についてご教授いただけますでしょうか? よろしくお願い致します。

    • ベストアンサー
    • PHP
  • 文字検索結果のリスト化で困っております

    文字検索の質問です。どなたか助けてください。複数のテキストファイルの中から指定した文字(2種類)を検索して、抽出した文字の行内容をcsvリストで作りたいのですが、方法が分かりません。秀丸エディタでgrepを使用すると検索できることがわかりましたが、ファイル名までの表示で指定した文字が抽出できずEXCEL化の方法がわからないのです。 日時=xx時cc分 利用者=YAMADA このような記述があるxxx.txtが1000個あります。1000個のテキストファイルから日時と利用者を抽出してYAMADAが何件あるかEXCEL化して利用率を調べたいのです。どうぞよろしくお願い致します。

  • 連続で複数の単語をGREPしたい

    Windows7端末でサクラエディタを用いてGrepしていますが、Grepしたい単語数が多いので困っています。イメージとしては以下のようにできれば良いと考えています。 ・検索したい単語のリスト C:\単語リスト.txt ・結果を出力するファイル C:\結果テキスト.txt(結果ファイルは単語ごとに出力しても可能) ・検索対象フォルダ(サブフォルダも検索) C:\SourceCode\ 単語リストから一行ずつ取得して検索対象フォルダから該当のファイル名と該当行を結果テキスト.txtに出力します。結果は一つのファイルにまとめて出す場合は、単語ごとにGrepした結果を分けて出力したいです。 もしくは単語単位に複数の結果テキスト.txtを出力しても構いません。 方法ご存知のかた教えて頂ければ幸いです。

専門家に質問してみよう