Regular Expression(正規表現) Part14 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
Regular Expressionスレです。 質問する場合は必ず実装言語や処理系ソフトウェア名を示してください。 前スレ Regular Expression(正規表現) Part13 http://echo.2ch.net/test/read.cgi/tech/1415149975/ 次スレは>>980 宜しく 天ぷら等2以降 >>583 俺が書いた糞(>>559 )より糞なコードが書かれて驚く 素直にパーサ使えよ >>583 のほうがスマートなのは一目瞭然でしょ ただ >>583 は こんな感じ 程度のものなのでツッコミ所があっても知らないよ mataタグでのcharsetは定型的でしか使われないんで、仕様的に色々な場合に対応するのは無駄 俺が使うなら、こんなので十分 /<meta[^>]*\scharset=(["'])((?:(?!\1).)+)/i マッチングテスト [1] <meta charset="UTF-8"> >>557 1. 失敗 >>559 マッチ >>583 マッチ >>586 マッチ [2] このスレのHTML 557 1. マッチ 559 失敗 583 マッチ 586 失敗 こんなバカが回答者してたのか 過去レス見ると前から張り付いてるようだね bregonig.dll 2017/01/17 Ver.4.10 非包含オペレータに対応 うーん、非包含にマッチする正規表現はいつか自分で作れるように なりたいと思ってたけど内部で勝手に作ってくれる時代になってしまったか〜 自分の知識は2013あたりで止まってるから浦島だ ab(?~ba)ba これを ab((?!ba).)*ba この従来通りの方式をベースに記述して、かつ、前者とまったく同じ 動作に書き直すことは可能かな? 両者の違いについては>>590 のリンク参照 (?~abc) これは↓とまったく同じ動作になると言って良さそう (?:(?!abc).)*(?:(?=abc).{1,2})? 否定したい文字列が固定長なら先読みで書き換え可能らしい 正規表現を言語化できるようなとこ知りませんか? /^ab/ これを入れると、 ↓ 「abで始まる」 と変換されるようなサービスって無いでしょうか? 視覚的に見れるサイトじゃなくて視覚的に作れるサイトがあったら便利かな メタ文字を覚える必要が無くなるし動作を把握しながら作れる そういうのが普及したらいいね そういうのとはちょっと違う&grepツールになっちゃうけど TresGrepってのが入力欄でのマウス右クリックから正規表現を指定出来たり 正規表現1文字入力ごとにエラーチェック⇒NGならエラーメッセージを表示したりと ちょっと便利 >>596 これいいですね。 ありがとうございます。 TresGrep使ってみたけど良くできてる 正規表現に何かしらの思い入れがあるのが分かる気がする 特に正規表現の複数行入力が出来るのはいい 自分は複数行入力が当たり前になるべきだと前から考えていて それが実装されててちょっと感動してしまった C#、System.Text.RegularExpressions.Regexの正規表現で xxの中を取り出すにはどうしたらいいのでしょう? ただし取り出したいのはトップのxxで、xxが閉じる前にyyがあるときはそのxxは無視という条件付きです 対象文字列 "<xx><xx><yy>111</yy></xx></xx><xx>222</xx><xx>333</xx>"; 試した正規表現 @"<xx>.*?[^(</yy>)]</xx>" 結果 <xx><xx><yy>111</yy></xx></xx><xx>222</xx> <xx>333</xx> 欲しい結果 <xx><xx><yy>111</yy></xx></xx> <xx>222</xx> <xx>333</xx> プログラムとはちょっと違うのですが、2chMateで荒らしをNGする正規表現を作りたくて悩んでます 日本語で書くと、 "http://" ;又は"https://" ;が合わせてn回以上出てきた場合(対象は複数の改行を含む文字列) にマッチするような正規表現って可能でしょうか? >>601 結果と欲しい結果の違いが改行しかないような >>602 n=3 (?si:https?:\/\/.*?){3,} >>603 迅速なご回答ありがとうございます。 この方法でうまくいきました! >>601 .NET Frameworkの正規表現は知らんけど、鬼雲でなら (?=<xx>)(<(\w+)>([^<]*|\g<-3>)*</\k<-2-0>>) これは最低限のものでイレギュラーなものには対応しない 文字列でエスケープされてるとかコメントが入ってるとか タグにタグ名以外の余計なものが入ってるとか(</a href=...>とか<br />とか) ペアでないタグがあるとか(<br>のような単独タグ,<xx>と</xx>のどちらかしかないとか) そういうのにも対応させるなら工夫して 一応、.NET Frameworkの正規表現の再帰については https://qiita.com/HMMNRST/items/15800514bbe66f504789 ありがと。もう少し単純にできるかと思っていたけどそんなに複雑になるのね 正規表現使わずにやる方向で考えてみます >>605 のリンク先見てやっつけで作ってみた <xx>(?>(?:(?!</?xx>).)*)</xx>|<xx>((?'open'<xx>(?>(?:(?!</?xx>).)*))+(?'-open'</xx>(?>(?:(?!</?xx>).)*))+)*</xx>(?(open)(?!)) ミスってた、>>607 はボツってことで・・ タグとタグの間の文字列の扱いが意外と難しい 確かにダメ質問者w 「xxが閉じる前にyyがあるときはそのxxは無視」という一見簡単そうなルールが予想以上に難しいようで 楽したいから正規表現使いたいのだけどあまり複雑になると楽じゃないからほかに逃げたくなる ぶっちゃけ欲しい結果が何なのか結局よく分かってない <xx>(?:(?<tag><(?!yy>)(?<tagname>[a-z]+)>)*\d+(?<-tag></\k<tagname>>)*(?(tag)(?!)))*</xx> ID変わった その表現だと <xx><xx><yy>111</yy></xx> 欲しい結果は<xx><xx><yy>111</yy></xx></xx> こういう尻切れになることが多い どういうことよ >>611 の正規表現で <xx><xx><yy>111</yy></xx></xx><xx>222</xx><xx>333</xx> にマッチングすると <xx>222</xx> と <xx>333</xx> にマッチするでしょ? <xx><xx><yy>111</yy></xx> はどこから出てきたの? 申し訳ないミス。"<xx>.*?</xx>"の1件目の結果だったw その正規表現だと2件マッチ 欲しい結果は>>601 にある3件 > xxが閉じる前にyyがあるときは これは直前ってこと? <xx><yy>111</yy></xx> にはマッチしないってことでいいの? >ただし取り出したいのはトップのxxで これだけで<yy></yy>があろうがなかろうが良いと俺は思ったんだけど yyがどうでもよければ <xx>(?:(?:<(?<tag>[a-z]+)>)*\d+(?:</(?<-tag>\k<tag>)>)*(?(tag)(?!)))*</xx> かなぁ 閉じる前というのは直前という意味で 対象が"<xx><xx><yy>111</yy></xx></xx><xx>222</xx><xx>333</xx><xx><yy>444</yy></xx>" の場合は、<xx><yy>444</yy></xx>を無視したの3件マッチにしたい >>611 と>>617 ベースできそうだからがんばってみます。ありがとう まぁスタック使う構文が必要な時点で正規表現向きでないのは間違いない 本来の数学的な正規表現という意味では向いてる質問なんだけどね これぞ正規表現の仕事っていう質問 でもプログラムの検索で使う正規表現ではなかなか使われないね >>607 を修正 <xx>(?>(?:(?!</?xx>).)*)((?'open'<xx>(?>(?:(?!</?xx>).)*))+(?'-open'</xx>(?>(?:(?!</?xx>).)*))+)*</xx>(?(open)(?!)) これは>>605 のリンク先の例を↓のように書き換えただけ < を <xx>・・・ > を </xx>・・・ \A を <xx> \z を </xx> 「・・・」 は<xx>または</xx>の間に挟まれている文字列 >スタック使う構文が必要な時点で ああ、その通りだ、(r+s+)+ だけでは作れない 間違い \A を <xx> 正しくは \A を <xx> ・・・ >>611 のはミスってるね <xx><b><a>111</a></a></xx> にマッチする <xx><b><a>111</a></b></xx> にマッチしない この問題は>>617 で修正されてる ()* \d+ ()* のところが0回以上のループで正しく動くのは面白いな 一番外側の (?: )* はいらないかも (?# 主要部) <xx(?&Attribute)>(?&innerText)(?&roop)?+</xx> (?# 定義部) (?:|(?!) (?'Attribute'(?:\s[^>]*+)?+) (?'singletag'br) (?'tagname'[a-z][a-z\d]*+) (?'innerText' (?: [^<]*+ | <(?&singletag)(?&Attribute)> )*+ ) (?'roop' <(?'tag'(?&tagname))(?&Attribute)> (?&innerText)(?&roop)?+ </\k'tag+0'> (?&innerText)(?&roop)?+ ) ) こだわった点 ・主要部と定義部に分けて全体の構造が分かりやすくした ・繰り返しは全て強欲。無駄なバックトラックをさせない ・再帰には * を使わず、部分呼び出し自身に繰り返しをさせている ・定義部は (?:|(?!) 〜 ) として定義部がサーチに使われるのを避けている >>605 には ([^<]*|\g<-3>)* という部分があって ([^<]*)* というバックトラック処理がえらいことになる部分があって気になった あと再帰を使ってるのにループを * にさせているのを見て * を使わずに書けるはずだと思って作ってみた こういう書き方をした正規表現をサクラエディタで使おうとすると 1行に繋げなければならない、これでは不便すぎる 鬼雲の強力な正規表現を快適に使い倒せるようにするべき 出来れば複数行で書いた正規表現を1行に繋げる機能が欲しい そうすればここのような掲示板に貼るときに便利 逆に1行で書かれた正規表現を複数行に直す機能も欲しい 手動でいちいち改行を入れる手間が省けて快適になる この2つの機能は正規表現ライブラリに実装されることが望ましい そうすれば他のテキストエディタの作者も気軽に実装出来るようになる 正規表現に新しいメタ文字が作られたときの対応も容易になる 出来れば定義用の新しいコマンドが欲しい 定義のためのカッコなのにキャプチャが有効になってたり、 正規表現オブジェクトが無駄に肥大化してしまったりするから >>626 > 出来れば複数行で書いた正規表現を1行に繋げる機能が欲しい ここはム板なので言い出しっぺの法則が適用されます >>628 テキストエディタの正規表現の入力ウインドウに付けて欲しいんだ 次世代のテキストエディタは↓こうなって欲しい 1、画面をいっぱいに使って正規表現の複数行の記述が出来る 2、複数行で書かれた正規表現を一行に繋げるボタン 3、一行で書かれた正規表現を複数行に展開するボタン これがスタンダードになるといいな extendedフラグを付けて鬼雲に渡せば、複数行で処理してくれる。 エディタ側で1行にくっつけたりする必要はない。 >>632 そういうことじゃないんだな、>>626 を読んでね ちなみに複数行の正規表現を一行に繋げるのはかなり簡単なんだけど 一行で書かれた正規表現を複数行に展開するのはかなり難しい 正規表現のパーサを作るということになるから だから正規表現ライブラリに実装されることが望ましい ライブラリの作者なら細かい挙動まで把握しているから正確なパーサが作れる 逆にテキストエディタの作者がやろうとすると動作を把握しきれずに 不完全なものになったり、実装を諦めたりすることになりかねない 複数行をスタンダードにするためにはライブラリ側での実装が必須となる >>634 bregonig.dllはプログラミング用のライブラリをテキストエディタでも 使えるようにしたっていう感じなのでプログラミングに必要のない機能は 付けたくないと思う、管理が大変になるからね だから次世代の正規表現ライブラリと次世代のテキストエディタに期待 ちなみにテキストエディタに重きを置いたライブラリならこんなのが可能になるはず 検索:( red(?'color='赤) | blue(?'color='青) | yellow(?'color='黄) ) 置換:\k'color' 対象テキスト: blue 置換結果:青 現状の bregonig.dll でこれが出来ないということはプログラミングでなんとかなる 機能は付けないということ テキストエディタのほうは改行をまたぐマッチの実現に苦戦してるようで この問題が解決しないと高度な正規表現は宝の持ち腐れになるだけなので 次世代のテキストエディタに期待しましょう >鬼車オリジナルの作者さん 別人だとは知りませんでした^^; xyz? を含まないものにマッチする正規表現 http://www.din.or.jp/ ~ohzaki/regex.htm#WithoutXY http://www.din.or.jp/ ~ohzaki/regex.htm#WithoutXYZ > fmcat =(retofm ..のところで導かれている正規表現は明らかにxyやxyzを含む正規表現だけど これは単なるミスなのかな?こんな難しいことをやってる人がこんなミスを 見逃すとはとても思えないから何か違うものなのかなぁ・・ >>637 > fmcat =(retofm で始まる3行のところの正規表現についてですよ? (〜)* x (〜)* yz の形なので明らかにxyzにマッチします *y(x*[^xy]y*)*x* は誤植でしょうけど・・ やっぱり間違いなんですかね? プログラムを使って自動的に算出してるようなのに・・ 俺もわからんけど、prologらしいから、括弧や表記はスタック順になってるとかでは? >prolog なるほど、"xyを含まない正規表現" のところに grail って書いてあったのは prologとやらの実行ソフト名だったのか https://github.com/RichardMoot/Grail これの使い方を調べれば謎が解けそうですね 暇なときに試してみます、ありがとう 検索対象文字 <test>a="akari"desu</test> 正規表現 a="*" で、検索結果が「a="akari"」でなく、「a="」しか取得できないのはなぜでしょうか? a=\".*\" メタ文字(ダブルクォート)をバックスラシュでエスケープ .(ピリオド)で任意文字で0文字以上(アスタリスク)をつければ とりあえずイケル それでも意図どおりにマッチングしないことは予見できる ワイルドカードと混同しちゃってるのか ワイルドカードと正規表現を同時に使えるTresGrepなら動くかも OZk G L /sg ohzakiさんゲームのリンク な気がしたので貼る、最近更新したばっかりやん ゲーム関係のリンク http://www.din.or.jp/ ~ohzaki/game.htm >>643 ワロタw 正規表現の*とワイルドカードは違うぞ。詳しくはググれ。 多分a="[^"]*"でいけると思うけど詳しくはググれ。 ちょいと質問させて a="[^"]*" と書くことが多いんだけど a=".*?" と書くのとで結果に違いでるのかな? あと、.*?は使えない正規表現の処理系があるんじゃなかったっけか。詳しくは(ry >>651-652 なるほど、ありがとうございました 1、<test>a="[^\"]*"</test> 2、<test>a=".*?"</test> この2つが↓これにどうマッチするか試してごらん --------------------------------------------------------------------------- <test>a="pokemon"(^-^)</test> <test>a="doramon"</test> ---------------------------------------------------------------------------- >>654 サンプルありがとう でも、そういった検索/置換対象の場合だったら .*? は最初から考えないとは思う この誤爆のことに注意を払えているなら .*? で問題ないよ [^"] はそういう心配をしなくて良くなるからこっちを予防的に使うのもあり # 文字列 xy を含まない正規表現 $states = 3; @matrix = ( # E A p q ※ A は求める答え [qw(X X E E)], # A = p + q = pε + qε [qw(E X [^x] [^xy])], # p = p[^x] + q[^xy] + ε [qw(X X x x)], # q = px + qx ); # 文字列 xyz を含まない正規表現 $states = 4; @matrix = ( # E A p q r ※ A は求める答え [qw(X X E E E)], # A = p + q + r = pε + qε + rε [qw(E X [^x] [^xy] [^xz])], # p = p[^x] + q[^xy] + r[^xz] + ε [qw(X X x x x)], # q = px + qx + rx [qw(X X X y X)], # r = qy ); y*(x*[^xy]y*)*x* について考察 左右対称形、後ろから読めば yx を含まない正規表現になる x の後ろでは [^xy] しかマッチ出来ないようになっている {[^x]|x+[^xy]}*x* # 状態遷移図から導かれる正規表現 # ※ ここでは見やすいように ( ) を { } としている # 最後の x* は状態 0 から状態 1 への遷移を表している [^x]*{x+[^xy][^x]*}*x* # 分岐の繰り返し ( | )* の展開 ([^xy]|y)*{x+[^xy]([^xy]|y)*}*x* # [^x] を ([^xy]|y) に分解 y*{x*[^xy]y*}*x* # x+ を x* にすると中央の [^xy] が分解した [^xy] と # 同じを動作するので分解した [^xy] を消せる、完成 こっちのほうがスマートだ.. # 状態遷移図から導かれる正規表現 ([^x]|x+[^xy])*x* # [^x] を分解し、[^xy] と y にする ([^xy]|y|x+[^xy])*x* # [^xy] と x+[^xy] を1つにまとめる (y|(x+)?[^xy])*x* # (x+)? は x* に書き換えられる (y|x*[^xy])*x* # 分岐ループを展開して完成 y*(x*[^xy]y*)x* (a|b|c)* の展開についての考察 # (b|c) を1つのパーツと考えて {a|(b|c)}* を展開する a*{(b|c)a*}* # 分配の法則 a*{ba*|ca*}* # 再び (x|y)* の形が現れたのでここを展開する a*(ba*)*{ca*(ba*)*}* a=123、b=456、c=789 とすると ^(123)*(456(123)*)*(789(123)*(456(123)*)*)*$ (a|b|c|d)* の展開についての考察 a*(ba*)*{ca*(ba*)*}* の a は全て a* の形になっているのでこれを利用する a を (a|d) に置き換えることで分岐を1つ増やす (a|d)* = a*(da*)* なので a* を a*(da*)* に置き換えるだけで答えが求まる a*(da*)*(ba*(da*)*)*(ca*(da*)*(ba*(da*)*)*)* (a|b|c|d|f)* を求めたいときは同じように a* を置き換えるだけで求まる このように a* は分岐を無限に増やす入り口のような役割をする このスレで名前が挙がってたTresGrep、気が付いたらbregonig.dllにも対応してるじゃん プルダウンのモード切替で.NETの正規表現と切り替えられるのもいい感じ もうこれでサクラエディタのGrepはお役御免にできるかもしれない なんだけど・・・rubyの正規表現が全部使えるわけじゃないのに 「鬼雲検索」 を名乗るのはどうなんだろう >>663 ちょろっと試してみたけど戻り読みも後方参照も再帰もちゃんと動いたよ? 動かないのがあるならこちらで検証するよ〜 全角スペースを\u3000と書いた場合とか bregonigだとperl互換じゃない書き方は受け入れてもらえないわけで 自分は文字コードの知識が無いので迂闊なことは言えないから ちょっと調べたことだけ書いておくね ここで http://k-takata.o.oo7.jp/mysoft/bregonig.html \u0149 を検索してみるとbregonigでも使えてそうなことが書かれてたよ サクラエディタでいろいろ実験してたら \s が全角スペースにマッチした サクラエディタ向けの正規表現を作るときには気を付けないといけないな bregonigは鬼雲の機能限定版(perl互換の正規表現だけが動く)って話をどこかで読んだ記憶があったんだよね どうせやるなら本家onigmoのRuby版正規表現も全部動くようにすればいいのに、って思っただけなんだ ちょっと難癖に近いなとは自分でも思ってる \sもそうだけど\dに全角数字がマッチしちゃって痛い目に合うのもまれによくあること サクラに限らないんじゃないかね I/Fの問題だろう Onigmoの仕様では、\sは Unicode以外の場合: \t, \n, \v, \f, \r, \x20 Unicodeの場合: 0009, 000A, 000B, 000C, 000D, 0085(NEL), General_Category -- Line_Separator -- Paragraph_Separator -- Space_Separator ASCII外の文字を含むかどうかは ONIG_OPTION_ASCII_RANGE オプションに依存する。 とある 実際、サクラエディタで試すと、 2028(LS),2029(PS), 0009,000a,000b,000c,000d,0085, 0020,00a0,1680,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,200a,202f,205f,3000(SS) がマッチする なので、サクラエディタはUnicodeで鬼雲を使ってると思われる Janeの場合でも、StyleはSJISであり、XenoはUnicodeなので https://egg.5ch.net/test/read.cgi/software/1536058236/515 に対して、\d{6}がマッチするのはXenoのみである なるほど、dll からは ONIG_SYNTAX_PERL しか使えないから ruby を使い慣れてる人にとっては歯がゆいと.. > \dに全角数字がマッチしちゃって ですね〜、(?a) で防げるようなので覚えておきます レスが被ってしまった.. >>669 ありがとうございます サクラエディタはUnicode仕様で動いているんですね う〜ん、文字コードの話は難しいなぁ なおUnicodeの空白でも、上記のCc(0009〜0085)、LS,PS,Zs(Space Separator) 以外のCf(200b,200c,200d,FEFF)だとどうかなと試したが案の定マッチしなかった さすがは仕様どおりだ > 200b,200c,200d,FEFF サクラエディタにIMEパッドから打ち込んで試してみたら同じくマッチせず # 主要部 (?&sp) # 定義部 (|(?!) (?<sp> (?u) [\x{200b}\x{200c}\x{200d}\x{FEFF}\s] ) ) 自分がこれ使うことは永遠になさそうだけどとりあえず.. あるファイルパスがありディレクトリのN階層目までのみを抽出したいのですが、正規表現について教えてください 例えばこんな入力のリストがある場合 aaa aaa/bbb/ccc aaa/bbb/ccc/ddd/eee/fff で各リストに対して2階層目までを取得したい場合 aaa aaa/bbb aaa/bbb となるのが期待値です。 ((?:¥w+¥/?){1,2})とかしてみたんですが上手くいきませんでした、お手数ですがよろしくお願いします >>675 正規表現はプログラム言語や正規表現オブジェクトのオプションによって 動作がけっこう変化するので質問するときはそういうの書いてね [^/]+(?:/[^/]+)? ただしこれは正しいパスが与えられることを前提としているので注意 ./ で始まってたらどう数えるん / で始まってたら? >>676 ありがとうございます、perlが希望でしたので次回から書くようにします 例は2階層で固定のようですが、ちなみにn階層目とか可変で書くような場合は下記のような感じで良いでしょうか? [^/]+(?:/[^/]+){0,n-1} ああ、N階層までのマッチという質問だったのか、ごめんね それで合ってるよb 暇つぶしに鬼雲の再帰処理に欠陥がないか探してみたけど見つからなかった 例、\1 を空文字にマッチさせて再帰の無限ループを狙う ()(?<name>a|\1\g<name>c) 例2、<x> を複数使ってマッチするのが空文字ではないように見せかける (?<x>)(?<x>text)(?<name>a|\g<x>\g<name>c) ・perl 5.22 if ( "a" =~ /^\Fa\E$/ ) { print "match.\n"; } else { print "no.\n"; } # 結果: match. ・ サクラエディタ + bregonig.dll (ONIG_SYNTAX_PERL) 検索欄: ^\Fa\E$ テキスト: a 結果: 見つかりませんでした \F の意味が知りたい.. ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる