プロが教える店舗&オフィスのセキュリティ対策術

英・仏・独語の多数のテキストファイルから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ですが、その場合は、初歩的なことしかわかりませんので、アドヴァイスというより丸投げしてしまうことになります。

どうかよろしくご助言をお願いします

A 回答 (8件)

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ウムラウト文字を
記述できます。

この回答への補足

大変ご丁寧にご回答くださり、まことにありがとうございました。

アポストロフィとシングルクオートの件については、週明けに出社し次第確認してみたいと思います。

最後に一つだけ甘えさせていただければ、上記のVBSをフォルダ内のファイルを一括処理できるように変更できるでしょうか。

以前、既存のVBSを自分のタスクに合うようにカスタマイズしようと(WEB上のTipsやmsdnのサイトを参照しつつ)トライしたことがあるのですが、動かなかったり不具合が発生したりすることが多く、挫折してしまった経験があります。

いずれは、ちゃんと勉強したいと思いますが、今回はご教示いただけると助かります。

お手数でなければ、よろしくお願いします。

補足日時:2009/11/07 08:23
    • good
    • 0

No.2です。


> 最後に一つだけ甘えさせていただければ、上記のVBSをフォルダ内のファイルを
> 一括処理できるように変更できるでしょうか。

一括処理といっても、
・複数ファイルの検索結果は、1ファイルにまとめて出力か?
別々のファイルに出力か?画面に表示するだけでもよいか?
・フォルダ内のサブフォルダも再帰的に処理するか?
といったような要件を確認し、それにあった機能を作る
必要があります。

すみませんが、検索ツールの作成を丸抱えしたつもりはありませんので、
アドバイスだけ返信します。

(案1)
http://itpro.nikkeibp.co.jp/article/COLUMN/20060 …
の「grepを実行するプログラムのソースコード(VBScript)」
を参考にし、その中の
If Y>0 Then

End If
の間に今回のコードを組み込む。

(案2)
http://www.atmarkit.co.jp/fwin2k/operation/wsh04 …
を参考にして、WScript.Argumentsを使って入力ファイル名、出力ファイル名を
コマンドパラメータで指定できるよう改造する。
それができたら、検索したいファイルを1個づつ指定してコマンド実行する形で、
全ファイルを処理するバッチファイルを作成する。
    • good
    • 0
この回答へのお礼

ご助言ありがとうございます。

今回はマニュアル作業でタスクをこなしてしまいましたので、今後の勉強の参考にさせていただきます。

テキスト処理が多いので perl もいいかなと思い、入門書を買ってきました。(VBSの入門書ってあまりないんですね…プログラミング経験者にとっては、無料の解説サイトで十分なんでしょうね)

お礼日時:2009/11/08 22:44

#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アクサンテギュ
以下略
    • good
    • 0
この回答へのお礼

秀丸の仕様を確認していただきありがとうございます。

上記のユニコードのリストを見ていたら、やはり範囲指定できそうな気がしてきました。

今回は面倒な手順を踏んで土臭くタスクをこなしてしまいましたが、週明けに今後に向けてスマートな方法を考えてみたいと思います。

お礼日時:2009/11/07 08:38

> 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/sei …

>文字コード番号(Shift-JISのコードポイント)を指定する正規表現です。

という説明文がありましたので、ひょっとしたらUnicode やlatin-1の
コードで指定するというのはできないのかもしれません。
これまた環境によるのですが、Unicode でのコード番号を指定するために
\uXXXX という表記を許すものがあります。
秀丸エディタで使えるかはわかりませんけど。

話を戻して、本当にアポストロフィが使われているのなら
[A-Za-z']{12,}
でいけそうな気がします。が、ウムラウトなんかはどう表現されるんでしょう?

この回答への補足

エディタの仕様などについて詳しく説明していただき、ありがとうございます。大変勉強になりました。

>これ、実際に 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

補足日時:2009/11/06 19:32
    • good
    • 0

半角カナが全角に変換されてしまいました。



[a-zA-Z'\-ア-ン] ・・・このアとンは半角カナです。

この回答への補足

[a-zA-Z'\-ア-ン] (アとンは半角カナ)で試してみましたがダメでした。

ところで EmEditor で、
検索文字列: .*(\w{12,}).*
置換文字列: \1
で置換してみたところ、一見うまく12文字以下の単語を削除(つまり、12文字以上の単語のみ抽出)できたように思えたのですが、何故か
・12文字以上ではなく、12文字の単語のみ抽出される
・ところどころ、抽出漏れがあってセンテンスの一部が残る
などの問題が発生しています。

これは、バグなのでしょうか(EmEditor ver.9.03)?
それとも設定か何かの問題なのでしょうか??

この件についても判る方がいらしたら、ご助言お願いします。

補足日時:2009/11/06 16:31
    • good
    • 0

one-year-old boyは単語として扱われますか?



[a-zA-Z'\-ア-ン]はどうでしょうか。

UTF-8なのかLaten-1かで違うと思いますが。

この回答への補足

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

補足日時:2009/11/06 16:23
    • good
    • 0

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 …

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
------------------------------------------------------

この回答への補足

ご丁寧に説明いただき誠にありがとうございます。

実は、秀丸では \w が使えないため [a-zA-Z] で検索したところ、独語の ? や ? などがヒットしないために、EmEditorで \w を使用した手法に切り替えたという経緯があります(なぜか\wならOKです)。

現在、再度秀丸で文字コード範囲を指定した検索にトライしているのですが、[\x0x00010000-\x0x0010FFFF] や [\x0x0080-\x0x07FF] でも上記のような独語文字にヒットしません。

ヨーロッパ言語文字にヒットする文字コード範囲などご存じないでしょうか。

補足日時:2009/11/06 13:31
    • good
    • 0

ながらく縁がない「プログラミング言語AWK」にそんなのがあったと、久しぶりに本を開いてみたら、P.164に「単語の数え上げ」と云うのがありました。

要するに連想配列が扱える言語ならどれでも良さそうです。今時ならばpearlかrubyなんでしょうか。「12文字以上の単語」と云う制限もさほど難しくはないと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!