Regular Expression(正規表現) Part15

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2019/09/16(月) 22:25:11.87ID:enU8we0d
Regular Expressionスレです。

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

前スレ
Regular Expression(正規表現) Part14
https://mevius.5ch.net/test/read.cgi/tech/1489511075/


次スレは>>980宜しく
天ぷら等>>2以降
732デフォルトの名無しさん
垢版 |
2021/07/02(金) 16:56:02.25ID:dFaH8qnm
>>731
| の左右どちらに一致した場合でも \1 に置換している
ただし片方にしか \1 に対応する括弧がない——というのがミソ

左側 (<[0-9]+>) に一致したときの \1 は 一致した全体なので結果として何も変わらない
右側 [<>] に一致したときの \1 は空なので削除される
2021/07/02(金) 17:12:17.66ID:3MNaXJzy
<><abc><value<123<x>>/value><>
こういうパターンはあるのか?
2021/07/02(金) 17:17:38.07ID:+v1CDJ0v
> ●説明
> <数字>以外の<>を外したい
735デフォルトの名無しさん
垢版 |
2021/07/02(金) 17:22:56.52ID:TPqIrTa2
>>732
あーなるほど
すごいなあ
2021/07/02(金) 17:26:47.31ID:3MNaXJzy
>>734
だからもしこういうのがあるのなら、上の回答じゃダメじゃん
<abc>は消えないぞ
2021/07/02(金) 17:29:30.28ID:+v1CDJ0v
こいつ無能そう
738デフォルトの名無しさん
垢版 |
2021/07/02(金) 17:49:16.07ID:TPqIrTa2
size = 4
s1 = entry.get()
s2 = re.sub(r'(<\d+>)|[<>]|[\\/:*?"|]+', r'\1', s1)
ss = [re.sub(r'<(\d+)>', lambda m: f'{{:0{len(m[1])}}}'.format(int(m[1])+i), s2) for i in range(size)]

簡単な範囲リネームソフト作ってて、windowsで使えない文字外して<数字>はカウントアップ がしたかったのでこれで大丈夫のようです.たぶん
入力(スタート値) dir<001>のとき リネーム範囲が2ならdir001,dir002を生成するみたいな
739デフォルトの名無しさん
垢版 |
2021/07/02(金) 18:45:34.59ID:Y9y/b0vz
でもさー
結局のところ自分の理解できる範囲で対処できないとブラックボックスでしかないから保守できないよな
2021/07/02(金) 19:31:10.32ID:aZbrSReX
掲示板で説明できることには限界があるからな
741デフォルトの名無しさん
垢版 |
2021/07/02(金) 20:03:30.56ID:6v6/dX3F
>>736
なんの環境だと消えないんだろう
2021/07/02(金) 21:23:02.60ID:8o23sM1E
ネストがある構造物は、パーサーを使わないと保守できない。
Ruby のNokogiri みたいな、XML/HTML パーサー

正規表現でバグると、他人が手を出せないので、
結局、パーサーで作り直しになる

アンチパターンの常識

モジュール・デザインパターンの知識が無いから、
何にでも正規表現を使う、香具師と言われている
2021/07/02(金) 21:48:40.11ID:QH8xfbBh
ネストがある構造はRDBで管理するという方法もあるな
2021/07/02(金) 23:39:59.09ID:aZbrSReX
>>727 のパターンは構造を見てない
ノンマッチな><だってホイホイ喰っちまう奴なんだぜ
745デフォルトの名無しさん
垢版 |
2021/07/03(土) 03:31:09.01ID:mR1/t/06
manの解析させるルーチンで無制限にネスト潜るの一度だけ書いたこと思い出したわ
2021/07/05(月) 13:22:47.46ID:a0633hZA
1行に「半角スペースと全角スペースが3文字以上ある時」を検出するにはどうすればいいのでしょう?
2021/07/05(月) 13:38:25.68ID:yW7vm9zn
(.*\040|.*\201\100){3}
とかか
2021/07/05(月) 13:43:46.12ID:a0633hZA
>>747
ありがとう試してみます
2021/07/05(月) 13:46:58.03ID:yW7vm9zn
>>747
SJISだったらこうしないとだめか
(([^\201-\237\340-\357]|[\201-\237\340-\357].)*(\040|\201\100)){3}
2021/07/05(月) 18:52:47.25ID:jQnBoLSl
●Regular Expressionの使用環境
サクラエディタ

●検索か置換か?
検索(正規表現で色を付けるため)

●説明
各行の「CR」または「LF」の改行コード部分に一致(CR+LFは一致させない)

●対象データ
あ\r
い\n
う\r\n

●希望する結果
\r
\n

よろしくお願いします
751750
垢版 |
2021/07/05(月) 19:33:48.25ID:jQnBoLSl
なんとか自分で調べて見たんですが、下の正規表現で合ってますか?
[\r\n](?!\n)$
2021/07/05(月) 21:45:00.65ID:oDqG8EZQ
(\r(?!\n))|((?<!\r)\n)
でどうだろう
2021/07/05(月) 22:18:11.17ID:lQZs6uo5
\r$|[^\r]\n$
じゃダメなのかな?
2021/07/09(金) 02:51:04.10ID:Cp8DUWjQ
文中もしくは単独で特定の文字列がある場合を除く
ってどうやるの?
2021/07/09(金) 07:34:09.88ID:XAnKbPPo
^(?~特定の文字列)$
^(?!.*特定の文字列).*$
2021/07/09(金) 09:09:31.42ID:hfuqSqCj
わざわざ貪欲にする必要性がわからん
757デフォルトの名無しさん
垢版 |
2021/07/11(日) 13:43:32.51ID:MYTG6y7m
>>754
鬼雲に非包含オペレータを実装した話
https://qiita.com/k-takata/items/4e45121081c83d3d5bfd
2021/07/11(日) 13:46:58.01ID:MYTG6y7m
>>754
非包含パラメータの提唱者のスライドと論文
https://staff.aist.go.jp/tanaka-akira/pub/prosym49-akr-presen.pdf
https://staff.aist.go.jp/tanaka-akira/pub/prosym49-akr-paper.pdf
2021/07/11(日) 19:12:06.67ID:nwBpGTGG
近似解のなにが近似なのかわからん
2021/07/11(日) 21:26:31.70ID:I5zdxibD
>>758
×非包含パラメータ
○非包含オペレータ
2021/07/12(月) 09:02:05.45ID:twuyj4UD
>>759
他の正規表現とつなげると問題が起こる。
例えばコメントの直後にbbbが来るのを \/\*.*?\*\/bbb として
/* */aaa/* */bbb
にマッチさせると /* */aaa の部分も含んで全体がマッチしてしまう。
2021/07/12(月) 15:36:01.58ID:mfnmNh+4
なるほど
ありがとうございます
2021/07/12(月) 16:40:03.21ID:mfnmNh+4
でも少なくとも解2でいいんじゃないか
表現力もたいして変わらない
数文字減るだけののシンタックスシュガーに見える
2021/07/29(木) 13:50:04.06ID:GMofCqjV
●Regular Expressionの使用環境
cygwin grep

●検索か置換か?
検索

●説明
テキストファイルに含まれる改行コードの検索

●対象データ
\r\n(0x0d0a)と\r(0x0d)が混在しているテキストファイル

●希望する結果
それらを検出して \r\nに統一したい。

grep -n -U -P '\x0d'
で検索をかけるとヒットするが
grep -n -U -P '\x0a'
ではなぜか1行もヒットしない
バイナリで確認すると0x0d0aはちゃんと存在しています・・。

とりあえずまずは0x0aを検索にヒットさせたいです。
その後
grep -n -U -P '\x0d[^\x0a]'
のような感じで0x0dの後ろが0x0aでない行を検索して置換できれば良いかなと考えています。
よろしくおねがいします
765デフォルトの名無しさん
垢版 |
2021/07/29(木) 14:18:21.31ID:aFdGt9X4
無駄無駄無駄〜
2021/07/29(木) 14:21:22.66ID:J3IrN4Ey
>>764
-aも足してgrep -nUaPでも試してみては?
2021/07/29(木) 18:49:46.76ID:QYfnOwKH
0xが邪魔だったりして
2021/07/29(木) 21:48:27.13ID:j2JISquU
>>764
そのテキストファイルはASCIIなの?
UTF-16だったりEBCDICだったりしない?
2021/07/29(木) 21:52:11.90ID:j2JISquU
>>764
なぜかマッチしないのはcygwin付属のgrepコマンドのバグかもしれないし、
cygwin本体のバージョンを書くか
ダウンロードサイトも書くべきかと
2021/07/29(木) 21:56:20.74ID:j2JISquU
>>764
あとは-Uオプションを外してどうなるか試してみるとか
2021/07/30(金) 00:49:58.41ID:N3W+nBLQ
単純に\nがgrepに食われてるだけだと思う

オプションに-zを入れれば\0区切りになるから\nは残せそうだけど
ファイル全体が1行になるだろうからやりたい事は多分できない

\rを\r\nに統一したいなら各行の末尾以外の\rを\r\nに置換すれば良さそう
grepで検索だけして手作業で直すつもりなのかな
2021/07/31(土) 20:32:32.88ID:jvyZNadn
>>764
解決したの?
2021/07/31(土) 20:46:25.03ID:Op1DTI/B
テキストファイルなんだよね?
だったらテキストエディタで開いて改行コードをCRLFに指定して保存するだけで
改行コードは揃うと思うけど
俺の使ってるエディタでCRLF,CR,LFの3つを混在させたファイルでやってみたけど
全部CRLFに変わってくれたよ
2021/08/01(日) 06:07:28.90ID:jVmJEbam
grepは行単位で処理するが、行は\nで終わることになってる
>>771のいうようにgrepが\nを食ってしまうので\nは検索できない
行末にマッチさせたいなら\nではなく$を使う

が、改行コード変換したいだけならCygwinに最初から入ってるunix2dos/dos2unixでも使えばいい
2021/08/01(日) 21:54:31.32ID:9jBEmz65
>>774
単独のCR(\r)は古いMACに見られる改行コードだから
UNIXの改行LF(\n)でもDOSの改行CRLF(\r\n)でもないよ
2021/08/01(日) 23:37:51.19ID:jVmJEbam
>>775
dos2unix/unix2dosは旧macの改行も変換できるので問題ない
2021/08/18(水) 07:15:11.84ID:zZ9UTeBf
ニュー速VIP板

(?<=ニュー速)VIP(?=板)

↑これは分かるけど

(?=ニュー速)VIP(?<=板)

↑これが分からん
2021/08/18(水) 08:14:34.80ID:zKbbX4Ws
(?=ニュー速)VIP
VIP(?<=板)
これらに一致するものは有り得ない

(?=.*ニュー速)VIP
こうなら有り得る

先読み
(?=abc)
はabcの左側aの手前の「位置」に一致するもの
xabcとあればxとaの間の位置に一致

戻り読み
(?<=abc)
は先読みと反対でabcの後ろcの後の「位置」に一致するもの
abcxとあればcとxの間の位置に一致

つまり
(?=ニュー速) は「ニュー速」の「ニ」の手前の位置に一致するものなので
(?=ニュー速)ニュー速 で無ければ絶対に一致しない条件式となる
2021/08/18(水) 08:27:16.61ID:6oAKTuRB
焦りすぎ
2021/08/18(水) 09:49:36.54ID:zZ9UTeBf
>>778
ああ分かった /VIP(?<=IP)/ というのはVIPの右に(?)がある事からしてVIPのPの右の位置にマシンがカーソルを合わせて次に<という左矢印がある事からしてカーソルの左側にPがあるかどうかを探って次にその一つ左にカーソルを動かしてそのカーソルの左側にIがあるかを探るって訳か

文字にするとややこしいけどイメージはしやすいな
2021/08/18(水) 10:53:19.72ID:tjZSC3cn
> ニュー速VIP板ニュー速板

二つ目の「ニュー速」だけを対象にしたい
(?<=VIP板)ニュー速
前方に「VIP板」のある「ニュー速」

一つ目の「ニュー速」だけを対象にしたい
ニュー速(?=VIP板)
後方に「VIP板」のある「ニュー速」
2021/08/18(水) 11:43:36.15ID:h7WQfPHf
(否|肯)定(先|後)読みは、^(行頭)や$(行末)と同様に"位置"にマッチするメタ文字(「アンカー」)として機能する
2021/08/20(金) 00:20:17.08ID:qpe5vMDv
ここにある正規表現サンプルのURLを取得する正規表現ですけど
間違ってないですか?
https://www.megasoft.co.jp/mifes/seiki/s310.html

urlに'があるurlだと'の後が取得できなくなる。
2021/08/20(金) 01:44:25.03ID:kY+JN5EE
>>783
間違ってるけどメタ文字解説読めばそんなこと分かるだろ
2021/08/20(金) 03:11:03.15ID:WG/a2fPY
厳密なのはいつもの
http://www.din.or.jp/~ohzaki/perl.htm#httpURL
2021/08/20(金) 10:49:36.74ID:nGw5woYj
これなんで5matchsなの?
https://i.imgur.com/nxnFsqo.jpg
2021/08/20(金) 10:57:32.68ID:OdebcBr3
ピンクの線が5本表示されとるやろ
2021/08/20(金) 14:58:31.43ID:bheJjdjJ
(abc){0}(def){0}
2021/08/20(金) 23:05:42.97ID:P1i1BIPh
>>788
>>787
ああなるほど一文字ずつマッチする上に空文字もマッチするのか

でもtest stringをabcdefとして3マッチになるかと思ったら2マッチなのな
2021/08/20(金) 23:47:12.81ID:WG/a2fPY
基本的にgreedyだから
2021/08/21(土) 09:01:29.88ID:juYH2QqI
abc(def)?|def
空文字に一致しないよう書くべき
792デフォルトの名無しさん
垢版 |
2021/08/25(水) 01:56:14.92ID:DUWK9/dO
windowsなんですが、正規表現を使ってファイルのリネームしたいです

hofajkfjda.jpg
fasfdajl.jpg
というファイルがあった場合

new1-hofajkfjda.jpg
new2-fasfdajl.jpg
としたいです

連番を含むのですが、正規表現で可能でしょうか?
また、何のツールを使うといいでしょうか?できればlinuxとwindowsで共通で使えるものがいいんですが。
2021/08/25(水) 05:11:18.76ID:DJHRbWtG
それ正規表現の話じゃないよねスレチ
ファイル名降順(昇順)で頭に(new連番-)付加ならFlexible Renamerとか色んなリネームソフトで出来る
任意の順ならバッチやPowerShell
後は該当スレでどうぞ
794デフォルトの名無しさん
垢版 |
2021/08/25(水) 10:49:27.59ID:DUWK9/dO
正規表現では連番は無理なのですか?
2021/08/25(水) 11:00:10.58ID:1f33yFBx
不可能じゃないけど、近所のコンビニへ行くのに絶対にプライベートジェットで行きたいですとか言われてる感じ
もっと他に簡単で向いている方法があるでしょって話
2021/08/25(水) 11:02:04.86ID:pNx7VLY8
文字列の集合を表す記法が正規表現
連番という集合を示せるならできるかもね
自分は知らないけど
2021/08/25(水) 11:08:38.01ID:0azwHm+I
>>792
秀丸ファイラー

ファイル選択→「F2」→「Alt+2」、で連番リネームモードになる
798デフォルトの名無しさん
垢版 |
2021/08/25(水) 11:30:25.04ID:DUWK9/dO
>>795
了解です

>>797
flexible renamerにしました。
これより新しくて良いソフトってあるんでしょうかね。
2021/08/25(水) 11:40:19.51ID:b/tFJsW5
質問続けるならせめて礼くらい言ってからにしろ
そもそももうスレチなんだから他へ行け池沼
2021/08/25(水) 12:25:51.34ID:pNx7VLY8
>>798
>>793読んだ上でその書き込みなら流石に傲慢が過ぎる
2021/08/25(水) 13:21:49.43ID:T8xCLAXo
Ruby で作った。
fileutils のDryRun を使ったので、実際には実行されない。
結果を予測して、表示するだけ

require 'fileutils'

# 絶対パスのディレクトリ名の後ろに、* を付けること!
# . で始まる、隠し directory, file を除く

dir_path = "C:/Users/Owner/Documents/*.jpg"
target_dir = File.dirname( dir_path ) # ディレクトリパスだけを取り出す

Dir.glob( dir_path )
.select { |full_path| File.file?( full_path ) } # ファイルのみ
.each.with_index( 1 ) do |full_path, idx| # index は、1 から始まる

dest_path = target_dir + "/new#{ idx }-" + File.basename( full_path )

FileUtils::DryRun.move( full_path, dest_path )
end

出力
mv C:/Users/Owner/Documents/abc.jpg
C:/Users/Owner/Documents/new1-abc.jpg

mv C:/Users/Owner/Documents/xyz.jpg
C:/Users/Owner/Documents/new2-xyz.jpg
2021/08/25(水) 18:27:43.69ID:WqMYsX4p
複数行モード出なくても改行に一致させる事は可能ですか?
2021/08/25(水) 23:49:57.87ID:HwQGLaDN
一致と呼んでいいのか分からないけど$が改行に対応すると思う
文字セットには使えないけどab(c|$)みたいな分岐は可能
2021/08/26(木) 04:30:31.47ID:UZ8JqWyB
複数行モードって何?

mオプション(マルチラインモード)のこと?
それとも逆にオプションなし通常の場合やsオプション(シングルラインモード)のこと?

これの違いは解説でも読めば分かるけど
^ $ . の動作の違いってだけだから、\n,\rはどの場合でも有効だよ
2021/08/26(木) 08:14:39.00ID:nEHOiDh0
ありがとうございます
2021/08/26(木) 15:15:16.56ID:Yy835424
JavaScriptの正規表現によるmatch検索で、「10918」ピッタリの数が存在するか調べたいときのことです
「1091」でも検索に引っかかってしまいます。
どうしたらよいでしょうか

以下の条件では10918だけでなく1091でも検索に引っ掛かります
let a = 1091;
new RegExp(`(?<!\d+)${a}(?!\d+)`, "i")
2021/08/26(木) 15:17:19.26ID:Yy835424
>>806に追記
データは場合によっては「数字 数字 数字」になっており、そこから特定の数字だけ存在するか調べたいです
2021/08/26(木) 15:44:49.58ID:K931sT/w
\d+ → \\d
2021/08/26(木) 16:01:36.08ID:a0WUR1Wk
関係ないけどlookbehind内で正規表現が使えない言語とか多いのな
2021/08/26(木) 16:10:30.57ID:Yy835424
>>808
出来たありがとう
2021/08/26(木) 17:04:06.18ID:/x6E5kVC
区切りがあるならlook aroundする必要ないよね
2021/08/26(木) 19:13:53.21ID:1/m60R21
>>806
正規表現である必要ないんじゃない?
後読みの必要ある?
2021/08/27(金) 16:27:34.54ID:kYh+qXrW
aa●abbbcccd□ddeee
aa□abbbcccd●ddeee

両方にヒット表現をお願いします
2021/08/27(金) 16:35:14.96ID:zrk6+77w
^a
2021/08/27(金) 16:35:19.05ID:7nxBSwRn
そのまんまであれば
aa[●□]abbbcccd[●□]ddeee
2021/08/27(金) 16:47:10.72ID:kYh+qXrW
あ、そうか
aa●abbbcccd●ddeee
aa□abbbcccd□ddeee
はヒットしてほしくないのです
2021/08/27(金) 16:56:56.42ID:mGcBpOgN
じゃあ
(aa●abbbcccd□ddeee|aa□abbbcccd●ddeee)
2021/08/27(金) 17:06:33.96ID:kYh+qXrW
やっぱりそれしかないですかね。実際は
(.*●.*□.*)|(.*□.*●.*)
でこうなるのです
https://i.imgur.com/4VUmVsL.jpg
2021/08/27(金) 17:09:48.92ID:56S9Iaf9
全体をマッチ対象にしたいの?
820デフォルトの名無しさん
垢版 |
2021/08/27(金) 17:45:24.98ID:ldxLRyEW
>>816
aa([●□])abbbcccd(?!\1)[●□]ddeee
2021/08/27(金) 19:46:53.21ID:FthY+dex
EmEditorはしらないなー
(?m:(.*●.*□.*)|(.*□.*●.*))
2021/08/28(土) 05:34:33.30ID:Z+kCS9um
.+?([●□]).+(?!\1)[●□].+
2021/08/28(土) 08:18:57.05ID:3w95mdWV
>>818
そのダイアログはCtrl+Cでテキストコピーできると思うからググりやすいように
コピペしてほしいな

あとEmEditorはBoost.RegexとOnigmo(鬼雲)を使い分けられるから、
オプションでどっち使ってるのかも教えて
https://jp.emeditor.com/text-editor-features/history/new-in-version-15-7/
2021/08/28(土) 10:30:00.05ID:2Y0XlSPP
>>823
---------------------------
EmEditor
---------------------------
The complexity of matching the regular expression exceeded predefined bounds. Try refactoring the regular expression to make each choice made by the state machine unambiguous. This exception is thrown to prevent "eternal" matches that take an indefinite period time to locate.
---------------------------
OK
---------------------------

例示してもらった表現いずれも同様のメッセージが出てましたが、なんとOnigmoに変更したら出なくなりました。
いろいろ新しく知ることが出来ました
2021/08/28(土) 10:38:46.36ID:gjZsNEUJ
(?!\1)ってどういう意味?
2021/08/28(土) 11:02:34.45ID:o77XzsS5
>>825
「直前に"一つ目のパターン"がない位置」を指すメタ表現
2021/08/28(土) 11:25:40.94ID:m2ZH6alf
日本語的には"直後に"じゃね?
読んで行く方向、カーソルの前方だとしても直前だと意味が逆転しそう
2021/08/28(土) 13:02:42.57ID:rTzGvJSm
>>820
この(?!/1)は分かるけどその次の[●□]との繋がりが分からん
どういうこと?
2021/08/28(土) 13:33:13.98ID:gjZsNEUJ
ありがとう完全に理解した
\1 は ([●□]) のことを指してて
(?!\1)[●□] で前の ([●□]) で選んだものと被らないようにしてるわけか
830デフォルトの名無しさん
垢版 |
2021/08/28(土) 15:08:17.46ID:F14AY+cI
>>828
(?!\1) は「1つめの括弧で一致した内容はこの位置(の直後)には現れない」という言明

([●□]) が ● に一致したなら (?!\1) は (?!●)
([●□]) が □ に一致したなら (?!\1) は (?!□)

なので最初の [●□] と二つめの [●□] では必ず互いに異なる文字が一致する、という具合
2021/08/28(土) 15:43:56.56ID:rTzGvJSm
>>830
ああなるほどありがとう!
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況