[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/09 15:05 / Filesize : 175 KB / Number-of Response : 729
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

正規表現 Part6



1 名前:デフォルトの名無しさん mailto:sage [2009/05/06(水) 00:36:04 ]
正規表現(Regular Expression)スレです。

質問する場合は実装言語や処理系ソフトウェア名を示しておくと話が早いです。

【 前スレ 】 正規表現 Part5
pc12.2ch.net/test/read.cgi/tech/1212498448/

110 名前:デフォルトの名無しさん [2009/06/22(月) 11:09:00 ]
C#です
Match match = new Regex("AAA.+?BBB").Match(html);
としてAAAとBBBの間の文字列を抽出したいのですがなぜかできません

Match match = new Regex("AAA").Match(html);
Match match = new Regex("BBB").Match(html);
この二つはうまくいくのですが正規表現の書き方おかしいですか?
ちなみにAAAとBBBはhtmlタグです

111 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 11:28:41 ]
.+? って、1回以上の繰り返しが、あるかないか、という意味を意図してると思うんだけど、
そういう複合はできない。
0回以上の繰り返し .* でマッチさせる。

112 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:03:01 ]
>>111
> .+? って、1回以上の繰り返しが、あるかないか、という意味を意図してると思う
じゃなくて最短一致だろ

113 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:09:27 ]
最短一致です
("AAA".+?"BBB")は実際には
(<div id=\"comments\" style=\"margin-left:6px;margin-top:6px;\">.+?<button id=\"load_comment_button\"")
こんな感じです

114 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:09:34 ]
それだと、 . が改行にマッチしない事は理解してる?

115 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:11:26 ]
>>113訂正

("AAA.+?BBB")
("<div id=\"comments\" style=\"margin-left:6px;margin-top:6px;\">.+?<button id=\"load_comment_button\"")
こうです

116 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:15:40 ]
>>114
そうなんですか!?
どう書き換えればよいでしょうか

117 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:17:44 ]
RegexOptions.Singleline

111はどういう環境を想定してるんだろうね。

118 名前:デフォルトの名無しさん mailto:sage [2009/06/22(月) 12:25:48 ]
>>117
できました!ありがとうございました



119 名前:デフォルトの名無しさん mailto:sage [2009/06/24(水) 14:14:00 ]
●正規表現の使用環境
AutoHotkey 1.0.48.03 (Perl 5互換のPCRE)
lukewarm.s101.xrea.com/RegEx.html

●検索か置換か?
置換

●説明
""で囲われている箇所以外の行末コメントを除去したい。

●対象データ
key = value ; ccomment
key = "val ;lue" ; comment

●希望する結果
key = value
key = "val ;lue"

m`n)[\t ]+;.*(?=$) で 無差別除去まではできたんですが後方参照とか条件分岐の方法ががわからず。
key value comment 部はそれぞれ日本語の文字が入る可能性もあるんですが
AutoHotkeyのPCRE自体は2バイト文字が考慮されません(なので[:word:]とかは使えない状態です)
よろしくお願いします。

120 名前:デフォルトの名無しさん [2009/06/26(金) 11:50:32 ]
単純な正規表現は分かるのですが、これはどうすればよいでしょうか?

●正規表現の使用環境
PHP4

●検索か置換か?
置換

●説明
<del>タグにはさまれた任意の文字列を、文字数ぶん●で伏せ字にしたい。

●対象データ
昨日は<del>上戸さん</del>と飲みに行ったが、<del>17,000</del>円も奢らされてしまった。

●希望する結果
昨日は<del>●●●●</del>と飲みに行ったが、<del>●●●●●●</del>円も奢らされてしまった。

121 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 12:04:54 ]
>>120
preg_replace_callback使え。

122 名前:デフォルトの名無しさん [2009/06/26(金) 13:13:30 ]
>>121
そんな便利な関数があったとは、、。
ありがとうございました!

function toFuseji($matches) {
return $matches[1] . preg_replace("/./u", '●', $matches[2]) . $matches[3];
}

preg_replace_callback("/(<del>)(.+)(</del>)/", 'toFuseji', $str);

123 名前:デフォルトの名無しさん [2009/06/26(金) 22:30:17 ]
●正規表現の使用環境
C#2008 Regex.IsMatch

●検索か置換か?
一応検索

●説明
特定の文字列以外があるかをチェックしたい
SQLの話も混じりますが、要はSELECT文の後に
更新や変更するような命令があるかをチェックしたい
のです。
UPDATEとかそれぞれを書いていくのは漏れるかも
しれないのでSELECT、FROM、WHEREあたりを除いて
マッチさせるにはどう書いたらいいでしょうか。
試した文
^SELECT (?!.* [A-Z](?!ELECT |ROM |HERE ))

●対象データ と望する結果
マッチさせたい "SELECT * FROM AAA [UPDATE]"
マッチしたくない "SELECT * FROM AAA UPDATE"




124 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 22:52:35 ]
何らかの処理系なら、else節で処理しちゃう手もある。

125 名前:デフォルトの名無しさん mailto:sage [2009/06/28(日) 15:21:44 ]
>>123
念のため聞くけど…
まさかこれってSQLインジェクションの対処のためにやってるんじゃないよね?



126 名前:デフォルトの名無しさん mailto:sage [2009/06/28(日) 19:03:21 ]
『id059385,,』のように、固定文字列idの後にランダムな数列、その後ろにカンマがふたつ格納された変数から、最後のカンマをひとつだけ取り除きたいのですが、
for文で回ってる途中まれに同一変数に『,,,』のようにカンマが3つ連続して出てくることがあり、その場合は取り除きたくないので
原始的に(",,",",",$変数)のようなことができません
あくまで、固定文字列id、その後に数列、その後にカンマふたつという状況でのみカンマひとつ取り除く方法はないでしょうか

PHP5

127 名前:デフォルトの名無しさん mailto:sage [2009/06/28(日) 19:35:50 ]
最後に2つある時だけ取りたいならこうするかな
preg_replace('/(?<!,),,$/', ',', 'id059385,,');

128 名前:デフォルトの名無しさん mailto:sage [2009/06/28(日) 19:43:04 ]
>>119
これ難しいね。
excelなら、Instrrev使えばすぐだけど、正規表現だとどうやるんだろ。



129 名前:デフォルトの名無しさん mailto:sage [2009/06/29(月) 15:35:58 ]
>>119
Perlならこれでいけるっぽいけど、どうかな。だめかな

s/((?:[^;]*?".*?")*[^;]*)(?:.*?$)?/$1/mg

130 名前:デフォルトの名無しさん mailto:sage [2009/06/29(月) 18:07:37 ]
'"' 自体のエスケープはどうなっているのかと、 Shift_JIS への対応が気になるかな。

131 名前:デフォルトの名無しさん mailto:sage [2009/06/29(月) 22:27:07 ]
使用環境 WSH 検索
対象データ ^AAA(BBB(CCC)(ddd)))(FFF)(GGG)$

文末の、括弧記号を含まず括弧で囲われたものが連続しているもの
を検索したいけど挙動が違います。

1) /(?:\([^(]+?\))+$/ 検索結果→ (CCC)(ddd)))(FFF)(GGG)
2) /(?:\([^)]+?\))+$/ 検索結果→ (FFF)(GGG)

欲しい結果は2の方です。
文末の$を指定した時は通常とは逆に文末から左へ一文字づつ検索していると考えていいんですか?

132 名前:デフォルトの名無しさん mailto:sage [2009/06/30(火) 11:23:57 ]
>>131
そりゃ前から読んでもそうなるだろ

>\([^(]+?\)
「括弧の間に開き括弧を含まないもの」だから"(ddd)))"にもマッチする

>「括弧記号を含まず」「括弧で囲われたものが」「連続しているもの」
/(?:\([^()]+?\)){2,}/

133 名前:デフォルトの名無しさん mailto:sage [2009/06/30(火) 11:24:38 ]
「文末の」を見落としたスマン

134 名前:デフォルトの名無しさん mailto:sage [2009/06/30(火) 11:51:09 ]
> 文末の$を指定した時は通常とは逆に文末から左へ一文字づつ検索していると考えていいんですか?

そういう動作はしない。


135 名前:デフォルトの名無しさん mailto:sage [2009/06/30(火) 12:48:16 ]
/unko$/

/unko\r\n/
と同等と考えればわかりやすいだろう
(厳密には違うけど)

136 名前:デフォルトの名無しさん mailto:sage [2009/06/30(火) 23:16:49 ]
>>128-129
レスありがとうございます。
お礼が遅くてすみません。週末からリロードし忘れてました。

質問後自分なりに頭捻って、((".*?")|;.*(?=$)) , $2 とか無理やりやってたんですが
>129さんのでいけました。特に (?: )の使い方が参考になります。ありがとうございます。

今回の件とは直接関係ないんですが、除外文字列の表記がよくわからずいつも悩みます。
今回の例でいうと コメント文字列が「;」ではなく「 ;」(半角スペース+セミコロン)だった場合とか
(?:(".*?")|[\t ]+;.*(?=$)) , $1 みたいな方法で弾くしかないのかな。

137 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 00:15:50 ]
いや、普通にそっちのほうがシンプルでいいよ
なんであんなに複雑い書いたのかマジ俺イミフ。しにてえ

138 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 23:41:47 ]
.NETの話なんだけど
ttp://msdn.microsoft.com/ja-jp/library/bs2twtah(VS.80).aspx#BalancingGroupDefinitionExample
この例の正規表現がどうして <> の入れ子構造にマッチするのか上の解説読んでもよく分からないので誰か分かりやすく説明してください
「name2 グループと現在のグループの間隔をグループ name1 に格納します。」って文があるけど
この「name2 グループと現在のグループの間隔」っていうのはリンク先の例で言うとどこからどこまでなのかとか
格納するっていうのがつまりどういうことなのか、って言うレベルでさっぱり理解できてない・・・
最後の "(?(Open)(?!))$" にいたっては自分の中で暗号と化してるorz



139 名前:デフォルトの名無しさん mailto:sage [2009/07/02(木) 03:33:28 ]
わかりやすくは多分無理だな。

Openでカウントが増える。
Close-Open でそのそのカウントが減る。

んで、開きと閉じのアングルブラケットの数がバランスしていれば カウントは0になるので

"(?(Open)(?!))$";

の条件が (?!) ではなくなる。
この(?!) というのは要するに何にもマッチしないもの。


140 名前:123 mailto:sage [2009/07/03(金) 21:01:48 ]
>>124
うまく書けなかったので要素に区切ってチェックすることにしました。
>>125
SQLインジェクションって知らなかったけど、悪意のある入力の
チェックって感じかな?
入力文字はSQL文が前提で、そこまで重い意味合いのチェック
ではありませんでした。
SQLインジェクション対策って普通Regex.Escapeを通すのかな?



141 名前:デフォルトの名無しさん mailto:sage [2009/07/03(金) 21:07:18 ]
言語によるが、DB系のライブラリにバインディング機能があれば普通はそれを使う。
自作のお手製ライブラリはやめた方がいい。
DBによって攻撃の仕方が違うし、
よく知ってる人が作っていろんな人が使ってるやつの方がやっぱり圧倒的に安全。
詳しくはそれっぽいスレで聞いてくれ。

142 名前:デフォルトの名無しさん mailto:sage [2009/07/03(金) 21:16:14 ]
>>140
何のためにそんなことをしたいのか分からないが、
ユーザにSQLクエリを入力させて実行させたい、とかいう話なら、
クエリ式に対してチェックをするのではなくて、
データベースの更新が出来ないような権限でクエリを実行すべき。

143 名前:123 mailto:sage [2009/07/03(金) 21:16:15 ]
>>141
そうなんですか。調べてそっちの方向に変えてみます。
よく考えたらSQL文にRegex.Escapeなんて
なんの関係もなかった・・・。

144 名前:123 mailto:sage [2009/07/03(金) 21:20:04 ]
>>143
権限で〜ってのは思ってたんですが、触れない事情がありまして。
普通はそうなんですね。
スレ違いになってきたのでこの辺で終わっときます。
ありがとう。


145 名前:デフォルトの名無しさん [2009/07/04(土) 21:44:21 ]
●正規表現の使用環境
PHP ver 5.2

●検索か置換か?
置換

●説明
カッコ書きのある文章のカッコの中身を取得したい。
たとえば、
カッコ書き前(カッコ1(カッコ2(カッコ3)カッコ2後)カッコ1後)カッコ書き後
の文章に対して、後方参照で
arr[1] = カッコ書き前()カッコ書き後
arr[2] = カッコ1()カッコ1後
arr[3] = カッコ2()カッコ2後
arr[4] = カッコ3()カッコ3後
と言った感じで取得したい。

試した文
$preTxt = 'カッコ書き前(カッコ1(カッコ2(カッコ3)カッコ2後)カッコ1後)カッコ書き後';
$match = '/.*(\(.*\)).*/';
preg_match("$match",$preTxt,$arr);
結果
[0]= カッコ書き前(カッコ1(カッコ2(カッコ3)カッコ2後)カッコ1後)カッコ書き後
[1]= (カッコ3)カッコ2後)カッコ1後)

●対象データ と望する結果
上記記載

すみません。どなたかお願いします。

146 名前:デフォルトの名無しさん mailto:sage [2009/07/04(土) 22:10:12 ]
HTMLタグの中身を抜き出すのに近いね。
別の自作関数を作っておいて、

arr[1] = \1 & \7
arr[2] = \2 & \6
arr[3] = \3 & \5
arr[4] = \4

なんてのはどうかな。
もっとスマートな方法もあるかもしれないけど、今でもこれ使って動かしてます。


147 名前:デフォルトの名無しさん [2009/07/04(土) 22:43:50 ]
回答ありがとうございます。
でも、多分、俺って、あなたの思っている以上の馬鹿みたい。
全くもって、理解できないんですけど・・・・・・・。
もうちょっとわかりやすくしていただけると助かります。
って、馬鹿がわかりやすい解説って、わかってる人にはかなり難しいんだと思いますけど。
すみません。わがまま言って。

148 名前:デフォルトの名無しさん mailto:sage [2009/07/04(土) 23:28:20 ]
外側から攻めていって、カッコがなくなるまでループするとか
function foo($text) {
$kekka = Array();
$match = '/^(.*?)\((.*)\)(.*)/';
while (preg_match($match, $text, $arr) > 0) {
array_push($kekka, $arr[1] . "()" . $arr[3]);
$text = $arr[2];
}
array_push($kekka, $text);
return $kekka;
}
$arr=foo('カッコ書き前(カッコ1(カッコ2(カッコ3)カッコ2後)カッコ1後)カッコ書き後');
print_r($arr);



149 名前:デフォルトの名無しさん [2009/07/05(日) 12:38:53 ]
ありがとうございます。
完璧です。
ほんとにありがとうございました。!!

150 名前:デフォルトの名無しさん mailto:sage [2009/07/05(日) 12:56:11 ]
なるほど、賢いなぁ

151 名前:デフォルトの名無しさん mailto:sage [2009/07/05(日) 14:24:31 ]
147は138かな?

もうちょっと努力して説明してみるから少し待ってね。


152 名前:デフォルトの名無しさん mailto:sage [2009/07/05(日) 15:21:42 ]
147は145 で PHP5、.NET の138とは別の人、だと思うけど。

153 名前:デフォルトの名無しさん mailto:sage [2009/07/05(日) 16:48:27 ]
>>139,151
138です、レス遅れてすみません
自分で試しつつなんとか(?<name1>p1)+(.*)(?<name1-name2>p2)+ という表記なら
(p2にマッチした回数 - 1) 個だけ name1とname2のキャプチャを取り出して
(.*)の両端にくっ付けていく(ただし取り出すキャプチャの 最大数は (p1にマッチした回数-1) 個)のかな
という感じで理解し始めてますが・・・

それと?(Open) という書き方は ? と () までも含めて、Openを文字列リテラルとしてではなく
(既に同じパターンのより先頭部分で定義されている)Openという部分パターンの
グループ名だということを示すための表記法なんでしょうか?
こっちは試し方も良く分かりません・・・

154 名前:151 mailto:sage [2009/07/06(月) 03:10:01 ]
(?'Open'<)
というのは、named caputure でこの場合は < を Open という名前で捕獲するもの。
この場合は捕獲自体には意味はなくて裏で増やしているカウンタが重要。そして
(?'Close-Open'>)
この部分で Open のカウンタを1減らしている。< と > の数が同じであれば、
(?(Open)(?!))
まで来た時点で Openの値は0になっているはず。

で、この表現なんだけど (? (Open) (?!) ) が、? に続く部分正規表現が「真」であれば (?!) を
マッチの条件にするというプログラミング言語の if 〜 then 〜 みたいなもの。

解説は
msdn.microsoft.com/ja-jp/library/36xybswe(VS.80).aspx
にある。

そして Open が0でない==バランスが取れていなければ (?!) のチェックを
するのだけど、これは前回も書いたように絶対にマッチに失敗するというパターン
なので、全体を通してみるとバランスが取れていればマッチ成功。
そうでなければ失敗。という次第。



155 名前:デフォルトの名無しさん [2009/07/10(金) 10:33:02 ]
オライリーの「詳説 正規表現 第3版」を読んで疑問に思ったので質問します。

5章にある「IPアドレスへのマッチ」で、0から255の数字にマッチする正規表現のサンプルがありますが
 [01]?\d\d?|2[0-4]\d|25[0-5]

これだと、最初の選択で [01]? がオプションなので、たとえば "999" が "99" に
マッチしてしまうような気がするのですが、問題はないのでしょうか。
よろしくお願いします。

156 名前:デフォルトの名無しさん mailto:sage [2009/07/10(金) 10:43:53 ]
その後で、
 ^([01]?\d\d?|2[0-4]\d|25[0-5])\. (中略) \.([01]?\d\d?|2[0-4]\d|25[0-5])$
として前後の境界を指定して利用してるから問題ないんじゃないの?

数字だけを取り出したいのであれば、例えば、
 \b([01]?\d\d?|2[0-4]\d|25[0-5])\b
みたいに前後を指定する必要があるよね。

って、そういう話ではなくて?

157 名前:デフォルトの名無しさん [2009/07/10(金) 10:49:11 ]
>>156
あぁ、すみません。
たしかに ^ $ で境界を指定すれば問題ありませんね。
部分式ばかり考えていて見えませんでした。

ありがとうございます。

158 名前:デフォルトの名無しさん mailto:sage [2009/07/22(水) 01:41:17 ]
これ教えてーーーーー

●正規表現の使用環境
VB.NET

●検索か置換か?
検索

●説明
タグの外の文字列を順に取得したい

●対象データ
<html1><html2>AAA<html3>BBB<html4><html5>CCC<html6>DDD<html7>
だったり
<html1>AAA<html2>BBB<html3><html4><html5><html6>CCC<html7>DDD

●希望する結果

r = New Regex("(?<1>.+?)(?<2>.+?)(?<3>.+?)(?<4>.+?)" ←今こんな感じ

Console.WriteLine(m.Groups(1).Value)
で結果 AAA
Console.WriteLine(m.Groups(2).Value)
で結果 BBB
Console.WriteLine(m.Groups(3).Value)
で結果 CCC
Console.WriteLine(m.Groups(4).Value)
で結果 DDD




159 名前:デフォルトの名無しさん mailto:sage [2009/07/22(水) 02:48:28 ]
>>158
Match()一発じゃなくてMatches()で地道にいっこずつ切り出してみた。もっといい方法はあるかもしれん

Dim r As Regex = New Regex("(?:<.*?>)+(.+?)(?=<|$)")
Dim s As String = "<html1><html2>AAA<html3>BBB<html4><html5>CCC<html6>DDD<html7>"
For Each m As Match In r.Matches(s)
  Console.WriteLine("{0}", m.Groups(1).Value)
Next

160 名前:デフォルトの名無しさん mailto:sage [2009/07/26(日) 09:55:51 ]
正規表現、特にNFAって計算量が大きいので
実用上、30〜40文字ぐらいが限界だったように記憶してるのですが
NFAとDFAでの計算量ってO表記でどのぐらいでしたっけ?
wikiにそういう情報のせといて欲しい・・

161 名前:デフォルトの名無しさん [2009/07/26(日) 10:56:30 ]
PHPのpreg(perl互換)の話なのですけど、
/(?<=<div>)(.*?)(?=<\/div>)/is
はエラーにならなくて
/(?<=<div[^>]*>)(.*?)(?=<\/div>)/is
がエラーになる理由が分からないのですが、
なぜなのでしょうか

162 名前:デフォルトの名無しさん mailto:sage [2009/07/26(日) 10:59:13 ]
なぜと言われても・・・そう設計してあるから、としか言いようがないな

163 名前:デフォルトの名無しさん mailto:sage [2009/07/26(日) 11:01:24 ]
>>2 の「正規表現メモ」の (?<=pattern) の解説には

  固定長の文字列に対してのみ働きます(処理系による。可変長の文字列を許可する処理系もあります

と書いてある。つまりそういうことだ。

164 名前:デフォルトの名無しさん mailto:sage [2009/07/26(日) 11:06:41 ]
なるほど。これは固定長のみでしたか。
ありがとうございます。
別のルートから正規表現の方法を探す事にします。

165 名前:デフォルトの名無しさん mailto:sage [2009/07/26(日) 17:28:23 ]

/(?<=<div[^>]{0,99}>)(.*?)(?=<\/div>)/is

可変長は無理でもこの書き方({0,99})がOKな処理系もあるから試してみろ


166 名前:デフォルトの名無しさん mailto:sage [2009/07/27(月) 09:08:56 ]
>>160
DFAの計算量は自明でしょ。
NFAはパターンとテキストによって違うから一概には言えないんじゃないかな。


167 名前:デフォルトの名無しさん mailto:sage [2009/07/27(月) 12:33:41 ]
適当なことばっかり言うのはやめてください

168 名前:デフォルトの名無しさん mailto:sage [2009/07/27(月) 13:29:38 ]
セルフでコンプリートすればパーフェクトですよ



169 名前:デフォルトの名無しさん [2009/07/28(火) 16:26:27 ]
マッチする判定じゃなくて
正規表現書いたらそれを満たす全ての文字列を生成する
プログラムを書くのは難しいですか?

170 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 16:33:47 ]
^.*$

171 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 16:35:25 ]
正規表現によっては終わらない可能性があるわけだな

172 名前:デフォルトの名無しさん [2009/07/28(火) 16:37:23 ]
>>170
それをやると遅延評価的に必要な分だけ垂れ流すんです

173 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 16:37:58 ]
文字数限定すればできることはできる
指定字数の全ての組み合わせの文字列をその正規表現にマッチさせて
成功したものだけをリストアップすればいい

速度的にどれだけ実用になるかは不明
最適化するとなると論文レベル

174 名前:デフォルトの名無しさん [2009/07/28(火) 16:40:11 ]
フィルターにかけるのではなく
初めから有効な物しか生成しないものとします

175 名前:デフォルトの名無しさん [2009/07/28(火) 16:42:08 ]
>>174
よし、正規表現をパースすることから始めよう。

176 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 16:42:44 ]
等価な有限オートマトンをバックトラックしながらしらみつぶしに探索するような
プログラムを書けばできそうだな。

177 名前:デフォルトの名無しさん [2009/07/28(火) 16:56:58 ]
数学的に可能ですか?
僕が心配してるのは5次以上のn次方程式の一般解
を探そうとしていやしないかという事です

178 名前:デフォルトの名無しさん [2009/07/28(火) 17:00:53 ]
取り敢えずオートマトンを学ぶに適した良書を紹介して下さい



179 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 17:12:42 ]
> 正規表現書いたらそれを満たす全ての文字列を生成する

> それをやると遅延評価的に必要な分だけ垂れ流すんです

> 初めから有効な物しか生成しないものとします

> 取り敢えずオートマトンを学ぶに適した良書を紹介して下さい


何をしたいんだよ?お前は。
とりあえず学校の宿題なら自分でやれ。それか自分で調べろ


180 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 17:33:48 ]
ごめんなさい><

181 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 17:46:04 ]
>>179
とりあえずかの有名なこれでいいんじゃねーの?

ttp://www.saiensu.co.jp/?page=book_details&ISBN=ISBN978-4-7819-1026-0&YEAR=2003
ttp://www.saiensu.co.jp/?page=book_details&ISBN=ISBN978-4-7819-1027-7&YEAR=2003

182 名前:デフォルトの名無しさん mailto:sage [2009/07/28(火) 17:52:14 ]
>>181
あり^^

183 名前: [2009/07/29(水) 13:06:01 ]
聞くのもどうかと思ったんですが調べても解決しなかったので、聞きたいのですが
『正規表現の定義』ってなんですか?

184 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 13:11:58 ]
ほんとに調べたのか?

185 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 13:18:50 ]
文字列一致確認用プログラミング言語

186 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 13:19:32 ]
>>183
アルファベットΣ上の正規表現とは、
- 空集合 0
- Σ の要素 c
- r, s が正規表現のとき r + s
- r, s が正規表現のとき rs
- r が正規表現のとき r*
のいずれか。

187 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 13:23:42 ]
>>186
宿題は自分でやらせろよ。

188 名前:末吉 [2009/07/29(水) 14:16:10 ]
>>186
183は定義を聞いてるんだろ??



189 名前:デフォルトの名無しさん [2009/07/29(水) 15:17:02 ]
定義じゃん

190 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 15:56:14 ]
>>188

ここの「形式言語理論における正規表現」を見ろ

ttp://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE



191 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 16:05:59 ]
見るなら正規言語だろう。
ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A8%80%E8%AA%9E

192 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 16:46:52 ]
正規言語と正規表現は本質的には同じだけど違うものだし

193 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 17:11:51 ]
>>181は激しく良書なので啓蒙しとく

大学のオートマトンのテキストがひどかったので
この本は難しいだろうと思ってずっと敬遠してたが
これはとてもわかりやすかった
予備知識もほとんどいらない
(最初のほうは背理法だとか数学的帰納法のレベルから解説)

厳密な定義がちゃんと書いてあるが
それに先だって具体例をあげて説明がある

ただ、この本を読んでも>>169の実装に直接には役立たないかもしれない
(0+1)*1(0+1)+(0+1)*1(0+1)(0+1)のような正規表現を簡約して
より計算しやすい正規表現に変換する
といった最適化なら正規表現の代数的性質の章でちょろっと学べる

194 名前:169 mailto:sage [2009/07/29(水) 19:37:54 ]
直接役には立たなくても正規表ゲニストを目指す僕は
正規表ゲニスト名乗っててオートマトンも知らんのかと
馬鹿にされるのは嫌なので オートマトニストにもなります><

195 名前:デフォルトの名無しさん [2009/07/29(水) 19:59:04 ]
もういいから消えろよ

196 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 23:55:35 ]
aaa/bbb/ccc
aaa/bbb/ddd
aaa/ccc/eee
  ・
  ・
  ・

上のような文字列があって正規表現での検索時間(grepとか)を速くしたいと思っていますが、
高速化するために正規表現の合成?みたいなことができるようなライブラリってありますでしょうか?

検索したい文字列のリストはだいたい1行が30〜40文字程度で100行〜200行ほど
検索対象はファイルサイズで400Mbyte〜6Gbyteぐらいです。


197 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 00:09:32 ]
質問をもっと推敲しろ

198 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 00:10:30 ]
必要ない行はgrepで飛ばして読めばおk



199 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 00:13:49 ]
grepパイプでつなげば十分なんじゃね?

200 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 00:46:05 ]
パイプって言いたかっただけやんwww

201 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 03:14:06 ]
>>199
せめて -e を並べるか -f だろー。

202 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 09:14:17 ]
fgrep使うのが正解

203 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 12:45:55 ]
いつから言葉遊びをするスレになったのですか?

204 名前:デフォルトの名無しさん [2009/07/30(木) 14:47:20 ]
正規表現は秀丸でちょこっと\n\n\nとか^[a-z]くらいをいじっただけの初心者なのに、
Javaで、JavaのDecimalFormat用文字列を
Excelの数値フォーマット定義文字列に変換するフィルターを作ってます。
『他の人にやらせりゃいいのに…まあ調べればわかるやろ…』と思って始めましたが、
案の定、いきなり引っかかりました。www

1)引用符'を引用符"に変換する正規表現(ただし連続''は'自体を表すので"にしない)
2)''に囲まれていない浮動小数点EをE+に ([0#])(E)([0#])を\1E+\3に

なお、変換は単一の正規表現で行う必要はなく、
順序依存のある複数の置換をかけてもOKです。
ただしできれば、各フィルターは常に全文に適用したいと思います。
(不要なフィルターも通過させる)

最悪、一部の変換結果を絶対にユーザが使わない予約語に変換して避けておく…
ということも可能だと思いますが…

正直、いきなり1)で引っかかったのにはガックリきました。
フィルター文字列定義をpropertiesで外出しにして
出荷後もサポートで変更・追加できるようにしないとマズイな…

205 名前:204 mailto:sage [2009/07/30(木) 14:56:08 ]
作成中ソースの一部ですが、何をやりたいかは見当つくと思います。
これが論理的にダメダメと言うことはわかってます。

//////////////////////////////////
//シングルクォート囲みをダブルクォート囲みに

//'"'→\"
//まず引用符の中の"自体をエスケープする。\"
filter = new RegFilter("'\"'","\\\"");
filterlist.add(filter);

//シングルクォート囲みをダブルクォート囲みにする前に、
//連続''は'1個をあらわすので、"'"に変換してやる。
filter = new RegFilter("''","'");
filterlist.add(filter);

//シングルクォートをダブルクォートに変換してやる。
//ただしさっきのを除く必要がある。
filter = new RegFilter("[^']'","\"");
filterlist.add(filter);

//全フィルターを通す変換実行
sResult = executeFilters(sFormat, filterlist);


206 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 15:49:13 ]
うん、わかるね

207 名前:204 mailto:sage [2009/07/30(木) 15:56:54 ]
msdn.microsoft.com/ja-jp/library/2k3te2cs.aspxにいいのがありますた。
1)は
(')([^']+)(')→\"\2\"
''→'
の2つでいけるかなぁ…


208 名前:204 mailto:sage [2009/07/30(木) 16:24:35 ]
2)の浮動小数点EをE+にするのは、

引用符の中のEだけをEEに退避
([^']+)(')([^']+)(E)([^']+)(')([^']+)→\1\2\3EE\5\6\7
浮動小数点のEをE+に
(*.)([#0])(E)([#0])(*.)→\1\2E\+\4\5
退避したEEをEに戻す
(*.)(EE)(*.)→\1E\3

の3つで97%くらいは出来てるかなあ。
変換対象の最後が引用符のときに落としちゃうけど、まあ…



209 名前:204 mailto:sage [2009/07/30(木) 16:27:22 ]
*と.が逆だった。

引用符の中のEだけをEEに退避
([^']+)(')([^']+)(E)([^']+)(')([^']+)→\1\2\3EE\5\6\7
浮動小数点のEをE+に
(.*)([#0])(E)([#0])(.*)→\1\2E\+\4\5
退避したEEをEに戻す
(.*)(EE)(.*)→\1E\3


210 名前:204 mailto:sage [2009/07/30(木) 16:40:36 ]
最初から地にEEがあるとEになっちゃうか。
横着せずに引用符の中のEEだけをもどさないとだめだな。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<175KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef