- PR -

正規表現

1
投稿者投稿内容
hei
ベテラン
会議室デビュー日: 2006/09/07
投稿数: 78
投稿日時: 2007-01-14 17:22
お世話になっています。
裁判所名が書かれたテキストを扱う機会があったのですが、
次のように支部・出張所が続く場合でも必ず裁判所の後に改行が入っています。

札幌地方裁判所
札幌地方裁判所
室蘭支部
札幌家庭裁判所
札幌家庭裁判所
夕張出張所

これを、
札幌地方裁判所
札幌地方裁判所室蘭支部
札幌家庭裁判所
札幌家庭裁判所夕張出張所
のように各裁判所ごとにまとめる必要があります。

これをコーディングすることは難しくありませんし、
数は多くないので手動で行いましたが、
現在学習中の正規表現ではどのようにやればいいのかと考えています。

「改行・または文頭」から、「次の改行・または文末」の位置まで。
ただし、次の行が「裁判所」で終わっていない改行はマッチを許す

と考えて、

Dim text As String = "札幌地方裁判所" & ControlChars.Lf & _
"札幌地方裁判所" & ControlChars.Lf & _
"室蘭支部" & ControlChars.Lf & _
"札幌家庭裁判所" & ControlChars.Lf & _
"札幌家庭裁判所" & ControlChars.Lf & _
"夕張出張所" & ControlChars.Lf & _
"那覇地方裁判所" & ControlChars.Lf & _
"那覇地方裁判所" & ControlChars.Lf & _
"石垣支部" & ControlChars.Lf & _
"石垣簡易裁判所"
Dim pattern As String = "" & _
"(?:\n|^) (?#「改行」または「文頭」から)" & _
"(?<name>.+(?=\n.+裁判所.+\n))" & _
"(?=\n|$) (?#「次の改行」または「文末」の直前の位置まで)"

For Each m As Match In Regex.Matches(text, pattern, RegexOptions.IgnorePatternWhitespace)
MessageBox.Show(m.Groups("name").Value)
Next

としてみたのですが、うまくいきません。
肯定の先読みを次のように否定の先読みに変えても結果は変わりますがだめです。
Dim pattern As String = "" & _
"(?:\n|^) (?#「改行」または「文頭」から)" & _
"(?<name>.+(?!\n.+裁判所\n))" & _
"(?=\n|$) (?#「次の改行」または「文末」の直前の位置まで)"


これを正規表現で解決するにはどうすればいいのか、
ご教授よろしくお願いします。

hei
ベテラン
会議室デビュー日: 2006/09/07
投稿数: 78
投稿日時: 2007-01-14 18:25
初めに上げた例ではダメですね。
(?<name>.+(?=\n.+裁判所.+\n))の部分は
〜支部や〜出張所には裁判所は含まれていないので、すべて失敗します。
明智重蔵
大ベテラン
会議室デビュー日: 2005/09/05
投稿数: 127
投稿日時: 2007-01-14 22:15
\n(?!.*裁判所$)

を削除

EmEditorで動いたけど.netで動くか不明

[ メッセージ編集済み 編集者: 明智重蔵 編集日時 2007-01-14 22:18 ]
hei
ベテラン
会議室デビュー日: 2006/09/07
投稿数: 78
投稿日時: 2007-01-14 23:53
明智さん、ありがとうございます。

全体のパターンは、

"(?:\n|^)(.+)(?=\n|$)"

ということでしょうか?
EmEditorのフリー版を落としてみたのですが、
これでは行ごとにマッチするだけなので、
違うパターンですか?

paniponi-x
常連さん
会議室デビュー日: 2006/01/14
投稿数: 27
投稿日時: 2007-01-15 19:42
正直、正規表現で片付ける問題じゃあないと思いますが、
こんなところでしょうか?

コード:
Imports System
Imports System.Text
Imports System.Text.RegularExpressions
Imports Microsoft.VisualBasic

Module Mogera

Sub Main
   Dim strText as String

   strText = "札幌地方裁判所" & ControlChars.Lf & _
"札幌地方裁判所" & ControlChars.Lf & _
"室蘭支部" & ControlChars.Lf & _
"札幌家庭裁判所" & ControlChars.Lf & _
"札幌家庭裁判所" & ControlChars.Lf & _
"夕張出張所" & ControlChars.Lf

   Dim ms as MatchCollection
   ms =  Regex.Matches(strText, _
       "^ .+? (?: (?! \n[^\n]+? 裁判所) [^\n]+)? $", _
       RegexOptions.SingleLine Or _
       RegexOptions.MultiLine Or _
       RegexOptions.IgnorePatternWhitespace)

   Dim m as Match
   For Each m In ms
       Dim s As String
       s = m.Groups(0).Value
       s = s.Replace(ControlChars.Lf, "")
       Console.WriteLine("'" & s & "'")
   Next
End Sub
End Module

hei
ベテラン
会議室デビュー日: 2006/09/07
投稿数: 78
投稿日時: 2007-01-15 21:40
paniponi-xさん、ありがとうございます。

>正直、正規表現で片付ける問題じゃあないと思いますが

私もそう思いますが、ちょうど勉強中だったので ^^;)

paniponi-xさんが書いてくださったコードをコピペして試させてもらいましたが、
行単位で出力されるようです。

で、なんとか私も考えまして、
とりあえず出来た気がします。
(もっと処理が高速な書き方がある気がしますが。)

Dim text As String = "札幌地方裁判所" & ControlChars.Lf & _
"札幌地方裁判所" & ControlChars.Lf & _
"室蘭支部" & ControlChars.Lf & _
"札幌家庭裁判所" & ControlChars.Lf & _
"札幌家庭裁判所" & ControlChars.Lf & _
"夕張出張所" & ControlChars.Lf & _
"那覇地方裁判所" & ControlChars.Lf & _
"那覇地方裁判所" & ControlChars.Lf & _
"石垣支部" & ControlChars.Lf & _
"石垣簡易裁判所"
Dim pattern As String = "" & _
"(?:\n|^)" & _
"[^\n]+(\n((?!裁判所).)+(?=\n))?"
For Each m As Match In Regex.Matches(text, pattern, RegexOptions.IgnorePatternWhitespace)
MessageBox.Show(m.Value)
Next


paniponi-x
常連さん
会議室デビュー日: 2006/01/14
投稿数: 27
投稿日時: 2007-01-16 00:14
引用:

heiさんの書き込み (2007-01-15 21:40) より:

paniponi-xさんが書いてくださったコードをコピペして試させてもらいましたが、
行単位で出力されるようです。

で、なんとか私も考えまして、
とりあえず出来た気がします。
(もっと処理が高速な書き方がある気がしますが。)




すみません。
一度作ったものをさらにコンパクトにしたときにちょっと間違えたようです。

コード:
"^ .+? (?: (?! \\n[^\\n]+? 裁判所) [^\\n]+)? $", _





コード:
"^ .+? (?: \\n (?! [^\\n]+? 裁判所) [^\\n]+)? $", _



にしてください((?: のあとの \\n の位置を修正)。
これで支部や出張所が泣き別れになりません。


スピード云々ですが、まあ対象がそんなに大きくなければそんなに
気にすることはないと思いますが

引用:

コード:
 "[^\\n]+(\\n((?!裁判所).)+(?=\\n))?" 





先読みと単一のキャラクタの読み込みを繰り返すのはオーバーヘッドが
大きくなることが予想されるので、それしか手段がないというのでなければ
避けたほうが無難です。

あとは RegexOptions のプロパティ(でいいんだっけ?)を良く調べてみると
良いと思います。

コード:
(?:¥n|^)"



という記述をすっきりできると思いますよ。

hei
ベテラン
会議室デビュー日: 2006/09/07
投稿数: 78
投稿日時: 2007-01-16 21:31
できました!
質問した内容だけでなく、RegexOptionの使い方もとても参考になりました。
paniponi-xさん、明智さん、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)