Regular Expression(正規表現) Part14 [無断転載禁止]©2ch.net

1デフォルトの名無しさん2017/03/15(水) 02:04:35.47ID:e01p03UP
Regular Expressionスレです。

質問する場合は必ず実装言語や処理系ソフトウェア名を示してください。

前スレ
Regular Expression(正規表現) Part13
http://echo.2ch.net/test/read.cgi/tech/1415149975/


次スレは>>980宜しく
天ぷら等2以降

475デフォルトの名無しさん2018/04/07(土) 12:21:20.06ID:BRhgC8GS
multilineのオプション付けて
;でsplitしただけじゃだめなん

476デフォルトの名無しさん2018/04/07(土) 12:23:00.56ID:BRhgC8GS
>>474
それが含まれる時点で無理に正規表現一行で書くのはいつもあきらめる

477デフォルトの名無しさん2018/04/07(土) 12:30:00.76ID:LBmouzwW
ちゃんとやるなら文字列中のエスケープされたシングルクォートとかも処理しないとダメだし正規表現でやるのはすごく大変だと思う

478デフォルトの名無しさん2018/04/07(土) 12:57:57.77ID:wQfk+GMe
正規文法ではかなり厳しい印象で, BNFの管轄だと思うおよね

479デフォルトの名無しさん2018/04/08(日) 06:27:09.85ID:1mmlbc0v
1. ; で分割して、配列に入れる
2. 配列の各要素から、余分なものを削除する

2 のルールを、厳格に決めればよい

Ruby で作る方が速い

480デフォルトの名無しさん2018/04/08(日) 11:04:16.11ID:YK+KPtHu
正規表現は置いといて
DB用意して""で囲まれた部分をテキストとしてDBに入れながらID取得
本文側はIDに置き換える
あとは正規表現を使っても使わなくてもいいが;で分割
最後にまたID部分に元のテキストを流し込む

481デフォルトの名無しさん2018/04/08(日) 13:00:20.92
そこであきらめんなよ!
正規表現だけで乗り切ろうという気概を見せろよ!

482デフォルトの名無しさん2018/04/08(日) 13:08:05.41ID:wO4VFvVz
(シングル|ダブル)クオート文字列って正規言語で表せる範囲にあるんかね?
文脈自由言語では表せるけど

483デフォルトの名無しさん2018/04/08(日) 13:27:19.00ID:aPw27k7Z
どの正規表現がつかえるのかがわからん
環境を明示してくれないとなー

484デフォルトの名無しさん2018/04/08(日) 18:18:43.83ID:1mmlbc0v
/\"([^\"]*)\"/ =~ 'a"bc"d'
$1 #=> bc

"〜" で、〜には、" 以外の文字列が入る

485デフォルトの名無しさん2018/04/08(日) 18:28:48.48ID:aPw27k7Z
"のエスケープや'もあるし
'a"b\"c'd"e'

4864732018/04/09(月) 10:33:55.69ID:Q+cYQrXX
沢山ご回答ありがとうございます。
皆さんのご意見を伺った限り、やはり正規表現一本では難しそうですよね…

はじめは前処理で既成のsqlパーサなどを通して、きれいに整形して別ファイルに保存してから処理する方法も検討していましたが、
できれば現物ファイルを生のまま読み込んで正規表現でなんとか行けないかなと思い試行錯誤していて、
うまい書き方が全然できなくてここに書き込みさせて頂いた次第です。

>>483
使用できる正規表現はPCREです。

具体的にはPHPで省メモリで巨大なSQLファイルを実行する仕組みが作りたくて
相談させてもらいました。自分の頭の中のアイデアでは
 1.fileをbufsize分readして
 2.正規表現でマッチするかチェック
 3.マッチしていたらそのSQLを実行。マッチした文より、先の部分は次の実行のためにバッファに積んで1へもどる
 4.マッチしていない場合は更にbufsize分read、2->4を繰り返す。
こんなイメージでした。

それを鑑みると、>>480さんのアイデアはちょっとありかなとも思います。
スレ違いなっちゃいますが、regexを使わずプログラム上でクオートの始まりと終わりを正しく
処理できれば随分楽できそうな気がします。一考の余地ありですかね?

487デフォルトの名無しさん2018/04/09(月) 12:10:15.13ID:M/BmQ9Z1
"'", "\""
'"', '\''

クォーテーション内にクォーテーションがある、入れ子状態が難しい。
クォーテーションを、\ でエスケープしたりもあるし

XML Parser とか、プログラム実行の命令木とか、解析ツールを使わないと無理。
プログラミングで何とかできる、範囲を超えている

そもそも、入れ子状態にどういうパターンがあるのか、
全列挙して考えるのが、非常に難しい

入れ子の入れ子とか、再帰的に入れ子するかも知れないし

488デフォルトの名無しさん2018/04/09(月) 17:17:14.98ID:4vJW9Ikj
>>486
こういう感じでどうだろう
[a-zA-Z](?:\\"|\\'|[^"';]|(["'])(?:\\\1|(?:(?!\1).))*(?<!\\)\1)*;
英数字で始まって、\"や\'は許す;で終わる文字列
頭に^\s*を付けたほうがいいかもしれないけど
文字列は、" ' "、' " '、" \" "、' \' 'は許す( ; もOK)

ところで、" ' " ' "とは書けるんだっけ?
こういう括弧のネストが可能なら、正規表現の方もネスト構文や条件構文を使わないといけないけど
(俺は使ったことはないけど)

489デフォルトの名無しさん2018/04/09(月) 17:44:25.66ID:4vJW9Ikj
ただし↑は、コメント文はないものとしてのこと

490デフォルトの名無しさん2018/04/09(月) 19:00:46.18ID:4vJW9Ikj
さっそくダメだった
"\\"

491デフォルトの名無しさん2018/04/10(火) 00:21:39.82ID:oEQHPFsL
仕様を確定させるのが難しい。
単なるテキストには、ルールが無いだろ

XML とか、プログラム言語には、仕様があって、
ルール違反の書き方を許さないから、プログラムで判定できる

だから、まずこう書いたらエラーにする、という仕様を決めるべき

492デフォルトの名無しさん2018/04/10(火) 01:17:02.18ID:IM3kTV8x
>>491
https://ronsavage.github.io/SQL/sql-2003-2.bnf.html
こいつのcharacter string literalとか読め
ちゃんと規格化されてるんだからさ
その上で正規表現で書くのは難しいって話

493デフォルトの名無しさん2018/04/11(水) 13:14:45.93ID:p/bo/Ju1
試しに Perl でやってみた。最も楽観的な想定ならこのくらいまでは手抜きできる。

use strict;
my $comment = qr/(?:--.*?\n)/ ;
my $literal_ch = qr/(?:\'\'|[^\'])/ ;
my $ch_str_literal = qr/(?:\'(?>$literal_ch*)\')/ ;
my $other_ch = qr/[^\';]/ ;
my $some_str = qr/(?:$comment|$ch_str_literal|$other_ch)/ ;
my $statement = qr/(?:$some_str*;)/ ;
my $text = '';
while (<>){ $text .= $_; while ( $text =~ s/^$statement// ){ print("Found:$&\n") }}

文字列リテラルの中の文字の記法に特に対処すべき拡張があるなら $literal_ch に加えれば良い。
" は識別子を書くためのものだが '、;、-- のどれかが入る可能性があるなら $other_ch と $some_str に加えればいいだろう。
多分、問題はそこではない。この例では行単位の入力だから面倒な問題を回避できているが、そうでない場合の問題だ。
たとえばコメントの始まりの - までしか読まれていないという場合。もっと読まなければコメントかどうか判断できない。
あるいは文字列リテラルの中で ' が現れた場合。それは文字列リテラルの終わりなのか、それともリテラルの ' を表す '' の 1 文字目なのか。
こういう処理を自分で書くのは難しくはなくても面倒だし、処理速度も遅い。だから結局 flex を使ったりする。

494デフォルトの名無しさん2018/04/11(水) 14:19:31.82ID:jfPKheqL
仕様通りのParser とか、構文解析ツールが必要

それらを使って出力された、抽象構文木を使うのがよい

495デフォルトの名無しさん2018/05/04(金) 19:16:13.25ID:kVAlpXQV
★タイトル
★★タイトル

上のものにマッチさせたいのですが、
^★.*$
としてしまうと、下まで含まれるのですが、どうしたらいいでしょうか

496デフォルトの名無しさん2018/05/04(金) 19:36:12.61ID:eD01Afe2
>>495
^★(?! ★).*$

4974952018/05/04(金) 21:14:35.89ID:L0LZvRGB
半角SP紛れ込んだわ

^★(?!★).*$

498デフォルトの名無しさん2018/05/05(土) 05:47:27.14ID:iaqxNbgL
↑解答どうも
できなかったです
ちなみにmeryというテキストエディタの正規表現です
何の言語かはわかりませんが

499デフォルトの名無しさん2018/05/05(土) 06:26:09.87ID:O3up5M1Q
https://regex101.com/r/YyXfr8/1

鬼雲みたいだし動くと思うんだけど, 先頭とか末尾に余計なスペース入ってない?

500デフォルトの名無しさん2018/05/05(土) 19:07:12.77ID:iaqxNbgL
↑ありがとうございます。行けました。
.*の前に否定を入れればいいんですね

501デフォルトの名無しさん2018/05/05(土) 21:57:45.66ID:+tF+3NSL
鬼雲…だと…?!

502デフォルトの名無しさん2018/05/07(月) 13:28:13.91ID:XtvW294Z
正規表現をちゃんと論理的に導きたいと思って参考になる本を
買ったら必要な予備知識に群とか環が出てきて即諦めた
正規表現周りの開発をしてる人達はすごい人達なんだなぁ
すごさを直で実感出来た

503デフォルトの名無しさん2018/05/07(月) 14:59:22.19ID:QMgv+0U5
用語に慣れてないだけだろ
やってることは大したことじゃない

504デフォルトの名無しさん2018/05/07(月) 18:08:31.65ID:XtvW294Z
まぁ膨大な時間と労力をかければ自分にも分かるんだろうけど
現実的じゃないんだよなぁ(人の何倍も時間かかるだろうし)

これからは正規表現技術者の努力に感謝しながら正規表現を
使おうと思います(^^)>

505デフォルトの名無しさん2018/05/14(月) 07:31:45.21ID:0PI4I4+g
JavaScriptによる正規表現チェッカー

くっそ長いので短縮
https://goo. gl/CE3aZ8

https://fatiherikli.github.io/fil/#eyJwYXRoIjoiSmF2YVNjcmlwdFRlc3QxLmpzIiwic291cmNlIjoiLyog5q2j6KaP6KG
o54++44Oe44OD44OB44OG44K544OIICovXG5cbi8vIOato+imj+ihqOePvlxudmFyIHJlID0gbmV3IFJlZ0V4cCgv
XFxkKy9nKTtcblxuLy8g44OG44Kt44K544OIXG52YXIgdGV4dCA9IChmdW5jdGlvbiAoKSB7LypcbmFhYVxuYmIx
MmJcbmM1NjdjYzg5XG4qL30pLnRvU3RyaW5nKCkuc3BsaXQoL1xcbi8pLnNsaWNlKDEsLTEpO1xuXG5jb25zb2x
lLmxvZyhcIlJlZ0V4cDpcIiwgcmUudG9TdHJpbmcoKSlcbmNvbnNvbGUubG9nKFwiVGV4dDpcIiwgdGV4dCk7XG5c
bnRleHQuZm9yRWFjaChmdW5jdGlvbihsaW5lKSB7XG4gICAgY29uc29sZS5sb2coXCJsaW5lOlwiLCBsaW5lKTtcbiA
gICB2YXIgcmVzdWx0ID0gbGluZS5tYXRjaChyZSk7XG4gICAgaWYocmVzdWx0KVxuICAgICAgICBjb25zb2xlLmxv
ZyhcInJlc3VsdDpcIiwgcmVzdWx0KTtcbiAgICBlbHNlXG4gICAgICAgIGNvbnNvbGUubG9nKFwicmVzdWx0OlwiLCBcIm51bGxcIik7XG59KVxuIn0

506デフォルトの名無しさん2018/05/15(火) 21:31:31.85ID:xchMEgzc
ちょっと修正
https://goo. gl/M2Fn68

507デフォルトの名無しさん2018/05/19(土) 02:57:37.83ID:F73VBvr9
Linuxに触れるまで正規表現に方言があるなんて知らなかった
基本正規表現だの拡張正規表現だの
vimの置換で悩んでたら原因がエスケープの有無が原因とかもうね
ある程度は使えるが先読みとか後読みとか僅かでも深入りすると余計に混乱する

508デフォルトの名無しさん2018/05/19(土) 11:08:45.44ID:rxs2hai/
小さい世界で囲い込まれてれば楽だよな
ただし何かの拍子ではみ出した時に世界の広さを知って己の無力さを痛感する
よくあるパターン

509デフォルトの名無しさん2018/05/23(水) 19:28:29.89ID:Au5e7VGg
僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』

QBPEH

510デフォルトの名無しさん2018/05/24(木) 10:47:44.54ID:cPlRxlDn
QBPEH

511デフォルトの名無しさん2018/05/25(金) 13:52:01.06ID:X/Hngdv+
HTMLの解析を正規表現でやりたいのですが

<a href="xxxxx"><img src="yyyyy" /></a>

という風に、<a> で括られた img の src だけを抽出したいんですけど
どうしたらいいのでしょう。

<a> で括られてない

<img src="yyyyy" />

は除外したいのです。

512デフォルトの名無しさん2018/05/25(金) 13:53:08.12ID:X/Hngdv+
あ、すみません

<a href="xxxxx"><img src="yyyyy" /></a>
<a href="xxxxx">あああ<img src="yyyyy" /></a>
<a href="xxxxx"><img src="yyyyy" />いいい</a>
<a href="xxxxx">あああ<img src="yyyyy" />いいい</a>
<a href="xxxxx"><img src="yyyyy" /><div>あああ<div></a>

みたいに、<a> の中は <img> 以外のゴミも入ってきます。
※ゴミは無視したい

513デフォルトの名無しさん2018/05/25(金) 14:10:36.40ID:dgrSTrid
>>512
^<a\b.+<img src="([^"]+)".+</a>$

$1

514デフォルトの名無しさん2018/05/25(金) 16:20:05.07ID:fgSfMucA
>>513
<a href=""></a><img src="1.jpg"><a href=""></a>

515デフォルトの名無しさん2018/05/25(金) 20:00:28.32ID:OUvr9ihJ
頑張ってみてもこの程度が限界
https://regex101.com/r/VYrYNO/1

で, >>511がHTMLの解析を正規表現だけでやる理由は何だ?
Pythonのhtml.parser, RubyのNokogiri, PHPならGoutter, それ以外の言語でも間違いなくHTMLパーサは誰かしら作ってる
そんな中で何故正規表現だけで?ぶっちゃけこういう用途には向いてない, というかHTMLの構文規則は正規言語を超えるんだけど, 分かってる?

516デフォルトの名無しさん2018/05/25(金) 20:29:09.95ID:rhJz1xPv
パーサかましてXPathで必要な情報だけ抜くのが基本だしな
どうしても使えないっていう理由があるなら仕方ないけど

517デフォルトの名無しさん2018/05/25(金) 21:21:37.93ID:lQiYp+1p
鬼雲限定
<a (?~</a>)<img src="([^"]+)"[^>]*>(?~<a )</a>

518デフォルトの名無しさん2018/05/25(金) 22:28:52.14ID:Cqv+6nk2
■変更前
004a34
A521n2
785b66

■変更後
0049934
99521992
7859966
----------------------

数値以外を99に置換したいです
お願いします

519デフォルトの名無しさん2018/05/25(金) 23:31:17.71ID:gd/oxjVv
木構造のものは、正規表現じゃ無理

1< 2< abc 3> 4>

2<からの最短マッチで、対応する3>を取れるけど、
1<からの最短マッチで、対応する4>を取れない。
3>にマッチしてしまうから

1< 2< 3< abc 4> 5> 6>

これでも、2<と5>をマッチさせられない。
最長・最短マッチでも、マッチしない

CSS セレクターを使う、jQuery, RubyのNokogiri などを使え。
これらの使い方は、ほぼ同じ

520デフォルトの名無しさん2018/05/25(金) 23:43:29.83ID:OUvr9ihJ
>>518
数値以外と簡単に言うが改行文字や空白等の扱いはどうするんだ
変換対象文字をちゃんと明示しないと

/[^0-9]/99/g

こんなもんが欲しいわけではあるまい
とりあえずASCII印字可能文字に限るなら

/[\x21-\x2F\x40-\x7E]/99/g

だが当然マルチバイト文字は対象外

521デフォルトの名無しさん2018/05/25(金) 23:44:35.69ID:OUvr9ihJ
\x40じゃなくて\x3Aだわ

522デフォルトの名無しさん2018/05/26(土) 10:42:28.41ID:oqQZJpqn
>>517
非包含オペレータか

523デフォルトの名無しさん2018/05/26(土) 17:59:00.22ID:xbMfHZm2
>>519
再帰を使えば、対応する括弧のネスト対応ぐらいならできるらしいよ(鬼雲、PCRE)
<([^<>]++|(?R))*>
   # [^<>]++は(?>[^<>]+)としてもよい(どっちもバックトラックしないと思う)
   # (?R)は、(?0)とも書ける
   # (<([^<>]++|(?1))*>)

\g<-n>を使ってもできる(鬼雲だけ?)
(<(?:\g<-1>|[^<>])*>)
   # \g<-1>は(?-1)とも書ける
   # ここでは\g<-1>を先に書いたが上と同じく後ろに書いても同じ

524デフォルトの名無しさん2018/05/26(土) 19:07:35.21ID:vUfk79H6
https://regex101.com/r/VYrYNO/1

なぁこれメンテしたいか?というか出来るか?なぁ?

(?i:<a(?:\s+[a-z][a-z0-9]*(?:=(?:"[^"]*"|'[^']+'))?)*>)
((?:
(?i:<img(?:\s+(?:src="([^"]+)"|[a-z][a-z0-9]*(?:=(?:"[^"]*"|'[^']+'))?))*(?:\s*\/)?>)
|(?i:<([a-z][a-z0-9]*)(?:\s+[a-z][a-z0-9]*(?:=(?:"[^"]*"|'[^']+'))?)*>(?1)<\/\3>)
|(?i:<[a-z][a-z0-9]*(?:\s+[a-z][a-z0-9]*(?:=(?:"[^"]*"|'[^']+'))?)*\s*\/>|.*?))*)
(?i:<\/a>)

525デフォルトの名無しさん2018/05/26(土) 19:08:54.60ID:vUfk79H6
アップデートするの忘れてたわ

https://regex101.com/r/VYrYNO/2

新着レスの表示
レスを投稿する