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以降
473デフォルトの名無しさん
垢版 |
2021/01/11(月) 15:31:25.19ID:zqhSwaSS
初学者なのでうまく伝わるか心配ですが、 固定長で末尾に改行が入っているレコードファイルを扱っています
その中で、末尾だけでなくレコード中にも改行コードが含まれるようなデータがあり、それを置換したいといった具合です。

UNIX上での話なので、Perlやsedで置換できればと思います。
よろしくお願いいたします。
2021/01/11(月) 15:41:19.51ID:8i1ZTkbL
sedはデフォルト行ベースなので改行コードを全部置換すればいい
2021/01/11(月) 15:43:13.55ID:92N2rfT4
/[\r\n]++(?!$)/@/g
こんな感じじゃね?分からんけど
2021/01/11(月) 16:15:14.39ID:rLqIFFRR
s/\r?\n/@/gm;

どうよ?
2021/01/11(月) 16:20:44.13ID:A2M5zvGV
固定長ごとに出てくる改行以外の改行ってことじゃね
改行含めて80文字固定長なら80文字目や160文字目以外の37文字目や53文字目に出てくる改行
2021/01/11(月) 17:26:33.52ID:8i1ZTkbL
あーすまんそういうことか
それだと固定長単位に読み取って置換と出力のループかな

while read -N10 line || [ "$line" ]; do
echo "$line" | tr -d '¥r¥n'
echo
done < input.txt
479デフォルトの名無しさん
垢版 |
2021/01/11(月) 17:59:11.32ID:Op1S7Ai1
やりたいことは、 >>477 さんの仰る通りです。
少ない情報の中、皆さん色々とありがとうございます。

明日以降試してみます、本当にありがとうございます。
2021/01/11(月) 18:31:58.04ID:RwOnRvzI
改行コードは、cr・lf・crlf の3種類あるのか?

固定長の末尾の改行の後には、何が入っている?
ヌル文字か?

例えば、100バイトの固定長で、内容が80バイトなら、
残りの20バイトには、何が入っている?

それとも、内容の80バイトの部分だけが、渡ってくるのか?
2021/01/11(月) 18:43:53.19ID:5PaUweSP
CR なんとかReturn
LF LineFeed
CRLF なんとかReturnLineFeed
2021/01/11(月) 20:39:57.39ID:F0XanEVZ
echo -en "abcde
a\ncde
a\rcde
a\r\nde
abcdef
a\ncdef
a\nc" |
sed -re ':b;y/\r\n/@@/;/.{5}/!{N;bb};'
2021/01/11(月) 21:38:18.11ID:6WXFekQD
>>471
CRLFは@2個に置換でいいんだよね?
CRLFを@1個に置換したら固定長ファイルとして
ファイル構造がおかしくなるわけだし
484デフォルトの名無しさん
垢版 |
2021/01/12(火) 17:48:10.93ID:fqpU06Zc
>>481 carriage
2021/01/14(木) 20:15:05.94ID:uu7IOQ/X
>>479
解決しましたか?
486デフォルトの名無しさん
垢版 |
2021/01/14(木) 20:19:20.00ID:eDcISF88
うざw
2021/01/15(金) 04:04:23.16ID:VxNLJyBo
先日質問させていただいた471です。
色々と試した結果、
perl -pe ‘s/¥r/@/g $INFILE | perl -pe ‘s/¥n/@/g > $TMPFILE

cat $TMPFILE | perl -e ‘while(read(STDIN, $tmp , 100)){print $tmp, “¥n”}’ > $OUTFILE

と言った具合に、改行を消してから固定長に区切って再度改行付与という形でうまくいきました!

皆さんに教えてもらった方法とは少し異なりますが、ここで質問しなければ検索ワードすら導き出せませんでした。
皆様には感謝してもしきれません。
ありがとうございました。
2021/02/02(火) 23:52:09.94ID:LuWw9dWt
[]で囲まれた単語は/\[.+\]+/gで見つかるけど
文中に複数[]で囲まれた範囲があるとうまくいかない
'['以降で一番近い']'にマッチさせたいんだがどうやるか教えて
2021/02/03(水) 00:24:53.98ID:SY/XoUH2
/\[[^\]]+\]+/g
2021/02/03(水) 01:04:29.59ID:UENZ/29T
>>489
ありがとう!
491デフォルトの名無しさん
垢版 |
2021/02/03(水) 18:02:08.71ID:CJ1qfEuB
英数字7桁[0-9a-zA-Z]の文字列から(改行を経て)先程とは異なる英数字7桁の文字列まで最短一致させる正規表現を書きたいのですがわかりません…

一つ目の7桁の英数字は変数fistに入ってます
new Reg(first +"(.*\n)*?"+ここから先がわかりません

どなたかよろしくお願いしますm(_ _)m
2021/02/03(水) 18:33:27.05ID:sadlF3mb
最短一致ということは行当たりが[0-9a-zA-Z]{7}ではなく別の文字列も含んでいそうな
つまり「0123abc\ndef4567」だけではなく「あいう0123abc\ndef4567かきく」もあるとか

見本出した方がいいのではないかな
2021/02/03(水) 18:41:43.46ID:q3Uucr84
とりあえずこんな感じであとは調整して
https://regex101.com/r/aLWgGd/1
2021/02/03(水) 19:08:15.83ID:CJ1qfEuB
>>492
すいません、簡単にするために設定をちょっと変えさせてください。
[0-9A-Z]
大雑把で大丈夫なんですが
あいうえお01ABC23あいうえお01abc23あいうえお01abc23  ←ここの01ABC23から
あいうえお01abc23あいうえお01ABC23あいうえお01abc23
あいうえお01abc23あいうえお01ABC23あいうえお01abc23
あいうえお01abc23あいうえお01DEF23あいうえお01abc23  ←ここの01DEF23まで切り抜きたい
あいうえお01abc23あいうえお01ABC23あいうえお01abc23
あいうえお01abc23あいうえお01HIJ23あいうえお01abc23

first = "01ABC23" が入ってるので、正規表現の最後を01DEF23にしたいのですが
[0-9A-Z]{7}から"01ABC23"だけを除外する方法がわからず困ってます。
2021/02/03(水) 19:12:17.69ID:CJ1qfEuB
>>494
訂正 「大文字と数字だけの7桁に設定変更させてください」って文言が抜けてました

>>493
すいません、その後の調整方法がわからないんです...
2021/02/03(水) 19:16:51.84ID:CJ1qfEuB
日本語がおかしくなってました

01ABC23〜01DEF23と切り抜きたいのですが、
first = "01ABC23"と入っているので、firstという変数を使いつつ[0-9A-Z]{7}から"01ABC23"だけを除外する方法がわからず困ってます。
497デフォルトの名無しさん
垢版 |
2021/02/03(水) 19:28:51.74ID:oLpXy7xv
>>496
"(?!" + first + ")[0-9A-Z]{7}"
2021/02/03(水) 19:41:14.94ID:CJ1qfEuB
>>497
ありがとうございますm(_ _)m
↓だと最短一致しないのですが、真ん中がおかしいのでしょうか?

let reg = new RegExp(first+"(.*\n)*?"+"(?!"+first+")[0-9A-Z]{7}");


改行を含めた最短一致は([\s\S]*?)か(.*\n)*?でできていたのですが、何故か最短にならず困ってます
2021/02/03(水) 19:49:30.28ID:CJ1qfEuB
>>498
真ん中とは+で繋げた"(.*\n)*?"の部分のことです
日本語すら怪しくてすみません
2021/02/03(水) 20:21:28.10ID:CJ1qfEuB
>>498
自己解決しました
スレ汚しすみませんでした
答えてくださった方々ありがとうございました
2021/02/04(木) 12:49:19.54ID:ynIf2rIG
[正規表現の[表現力[は]ネストに]勝てない]
※Perlの拡張とかは除く
2021/02/04(木) 15:31:37.02ID:7s9fZWEo
繰り返しの中で使う時、時間のかかる正規表現を避けたいが、結局試すのが一番
if x=="abc" と if x=~/^abc$/ の比較など(簡単すぎる例)

重要なシステム内で複雑な表現を使う場合テストも重要だが、
どうしてもおかしくなったら調べる式になってしまう
503デフォルトの名無しさん
垢版 |
2021/02/06(土) 14:47:08.00ID:s4jA/y9i
お願いします

●Regular Expressionの使用環境
VBScript

●検索か置換か?
置換

●説明
[hoge]をブラケットごと消したい
[[hoge]]の場合は残したい

●対象データ
abc[hoge]def
ghi[[hoge]]jkl

●希望する結果
abcdef
ghi[[hoge]]jkl
^^^^^^^

否定戻り読み否定先読みで試してみたのですが、ブラケット2回の場合にマッチせずブラケット1回の場合にのみマッチさせる方法が分かりませんでした
よろしくお願いします
2021/02/06(土) 15:07:35.62ID:bKRJeVsu
(?<!\[)\[hoge\](?!\])
2021/02/06(土) 16:56:52.18ID:EC31O1b+
>>503
VBSには否定戻り読みは無いので、工夫するしかない
すぐには思いつかないけどもっといい方法もあるかもしれないのでググってみては?
愚直には、一つの方法として以下の場合に分ける
1) [hoge]で始まる場合
2) 文字列があって [ 以外で終わって [hoge] がある場合
3) 文字列があって [ で終わってる場合、[hoge] があって ] が続かないこと

pattern : "^(?:\[hoge]|(.*?\[)\[hoge\](?!\])|(.*?[^\[])\[hoge\])(.*)$"
replace : "$1$2$3"

abcdef → abcdef
[hoge]def → def
[[abc]]def → [[hoge]]def
abc[hoge]def → abcdef
abc[[hoge]]def → abc[[hoge]]def
abc[[hoge]def → abc[def
abc[hoge]]def → abc]def

下2つの場合が無ければもう少し簡易にできる
では[hoge]が2つ以上ある場合はどうするか?
すぐ思いつく方法としては、変換をループさせて、文字列に変化がなければ終わりとか
2021/02/06(土) 17:17:15.94ID:do+3t/u8
(¥[hoge¥])(?!¥])|[^¥[](¥[hoge¥])
https://regex101.com/r/xhea5T/1
2021/02/06(土) 17:31:09.15ID:nqcg0owg
(\[\[hoge\]\])|\[hoge\] → $1
https://regex101.com/r/xhea5T/2
2021/02/06(土) 17:40:46.95ID:bKRJeVsu
([^\[])\[hoge\]([^\]])
$1$2

(^|[^\[])\[hoge\]([^\]]|$)
$1$2
509デフォルトの名無しさん
垢版 |
2021/02/06(土) 17:44:51.10ID:s4jA/y9i
>>504->>508
ありがとうございます。
やってみます。
2021/02/06(土) 18:09:33.55ID:EC31O1b+
>>507
すばらしいです
>>506,>>508
残念
2021/02/06(土) 18:21:12.27ID:z9sN/DQY
発想の転換だな
目鱗
2021/02/06(土) 18:57:27.44ID:do+3t/u8
>>507
へぇー、これは面白い
2021/02/06(土) 19:33:52.91ID:nvvrKfMw
>>507
これは賢い
2021/02/16(火) 18:09:22.76ID:YYQsROlp
※間はタブです
●Regular Expressionの使用環境
サクラエディタ

●検索か置換か?
置き換え

●説明
(ABC|JKLHI7)を反転させたい

※(ABC|JKLHI7)→空に置き換え
ABC    DEF     123
FGH    JKL     956
GBN    MJK    HI7

↓こうなります

    DEF     123
FGH         956
GBN    MJK

(ABC|JKLHI7)を反転させて
ABC    
    JKL     
        HI7

というデータに置き換えたいです。
よろしくお願いいたします。


    
2021/02/16(火) 18:10:03.36ID:YYQsROlp
>>514
説明の部分に誤りがありました。
●説明
(ABC|JKLHI7)を反転させたい

でなく
(ABC|JKL|HI7)を反転させたい

でした。
2021/02/16(火) 18:30:01.16ID:9J2HaZUU
区切りは全角空白なのかい?
まあこんなのでどう?
(ABC|JKL|HI7)|[0-9A-Z]*→$1
2021/02/16(火) 19:29:55.89ID:YYQsROlp
>>516
ありがとうございます。
その発想まったくありませんでした。

ほしいものカッコで包んで|要らないもので置き換え
御見それしました。

ありがとうございます。
2021/02/16(火) 20:11:15.08ID:2Q6k9WLx
>>516
>>507再び
再度>>511感想
2021/02/17(水) 00:48:24.95ID:5uVmT0ro
XABCXのようなものまでABCにしたいなら、末尾を+?に変えた方がいいかも
2021/02/18(木) 23:51:52.71ID:sRdwF113
面白いなあ
逆に正規言語じゃない言語ってどんなのか気になる
2021/02/19(金) 07:25:19.97ID:1ojHRCGQ
言語?
2021/02/19(金) 18:55:29.37ID:Clj7wgUu
文脈自由言語とか文脈依存言語とか?
2021/02/19(金) 20:03:11.77ID:gWMDVcMR
文脈も先読み後読みrematch駆使すれば取れそうに思うけど、本来どこまでやっていいんだっけ 理論とか分からん
2021/02/19(金) 20:05:33.21ID:Wnqd+KEH
正規表現で記述可能な文字列の集合を指して正規言語という

が、その意味で使われたのかは定かでない
2021/02/19(金) 20:15:12.89ID:gWMDVcMR
取り敢えずその言語がn要素の有限集合ならstr1|str2|...|strn で表現できるのでは
文字列の長さを制限して、有限の文字集合なら
すげーつまらないけど
2021/02/19(金) 20:33:20.22ID:gWMDVcMR
無作為な文字列から、特定の言語に属する部分列を検出しろ、って問題にどれだけ簡潔に答えられるかってことだよな
どう計ったものか
2021/02/20(土) 01:01:18.47ID:yNkkv6Pq
AIに正規表現を設計させたらどんなものになるのだろう
2021/03/03(水) 06:22:13.41ID:7UFtTk12
●Regular Expressionの使用環境
python 3.x

●検索か置換か?
検索

●説明
ここをアクセスの次に出てくるURL(ttp://xxxx2/)をとってきたい
pattern = re.search("▼ここをアクセス.*(http.*\n)+?",a_text,flags=re.DOTALL)
複数行検索してるが最後のURLをとってきてしまう


●対象データ

URL1です
ttp://xxxx2/



 □       【▼ここをアクセス】
ttp://xxxx2/

URL2です
ttp://xxxx3/

●希望する結果
ttp://xxxx2/
2021/03/03(水) 06:44:56.40ID:lklpa5qm
> "▼ここをアクセス.*(http.*\n)+?"
python分からんけど
"▼ここをアクセス.*?(http.*?\n)"
2021/03/03(水) 07:02:17.82ID:h6piMY+h
>>529
レスサンクスですが、最後のttp://xxxx3/を拾ってきてしまいます
2021/03/03(水) 07:20:09.73ID:h6piMY+h
自己解決
"▼ここをアクセス.+?(http.+?)\n"
でいいみたい
2021/03/07(日) 14:22:59.84ID:Fo2Np7TJ
正規表現ってパズルとしては面白いけど
https://oraclesqlpuzzle.ninja-web.net/regex/index.html
可読性に問題あるんじゃね?
もっとマシな別の表記方法が必要じゃないか?
2021/03/07(日) 16:02:01.74ID:UIB+9WXp
自分が解らないものは悪
2021/03/07(日) 16:17:46.75ID:TNmQ0Vam
理解の過程で可読性に問題があるのではと疑問を抱き、
別の表記法の必要性を考え、
そのあと別の表記を実際に考えるところまでやると、
正規表現考えたケン・トンプソンすげーなってなる
2021/03/07(日) 17:26:15.98ID:FZPehcc/
>>532
> もっとマシな別の表記方法が必要じゃないか?
定期的にそう言うのが話題になるけどなかなかいい記法が無いんだよね
abc+
程度の簡単な奴と
^((?!aaa).)*((?=aaa)a((?!aaa).)*){3,5}((?!aaa).)*$
みたいなパット見よく分からん奴を1つの記法で簡単に見易くするのはなかなか難しい
2021/03/07(日) 17:53:05.78ID:AM/Ef9W/
やるとしたらアスキー文字以外の文字や記号を加えてもうちょっと役割を分散させると、機能を保持しつつ見やすくはなるが、そうすると今度はラテン文字圏の人が「自分が解らないものは悪」でいかに不要かを全力で説き始めると思う。
2021/03/07(日) 17:56:22.71ID:TNmQ0Vam
ASCII外の文字使うと入力コストが高くなるじゃん
2021/03/07(日) 18:04:15.76ID:4bEjyVwB
?とか^とか二つの意味を持つのは何とかしてほしかったよな
まあ分かるからいいんだけど
2021/03/07(日) 20:25:01.40ID:RWgRWesX
可読性を犠牲にして短く書けるのが正規表現
正規表現と同じことを可読性の高い表現で記述しようとすればなにかと長くなる
ただある一定以上複雑な正規表現は普通のプログラミング言語で書き直したほうが可読性も保守性も高い
2021/03/07(日) 21:12:54.42ID:0cOR0yWB
普通のプログラミング言語で正規表現ライブラリ使ってます
2021/03/07(日) 21:23:44.60ID:FZPehcc/
例えば.NETみたいに正規表現中に改行入れたりコメント書けるようにするとかして可読性を上げる試みはあるね
https://www.atmarkit.co.jp/fdotnet/dotnettips/582regexcomment/regexcomment.html
2021/03/07(日) 21:31:45.50ID:Fo2Np7TJ
>>539
それしかなさそうだ
2021/03/07(日) 21:36:49.39ID:6FoXMbth
>>541
改行してコメント書くのは Perl の正規表現でもできたりする
2021/03/07(日) 21:55:32.23ID:RWgRWesX
>>541
その例にある(?<url>.*?)みたいな名前付きキャプチャも
可読性を上げられる数少ない要素だと思うけど
2021/03/07(日) 22:46:53.20ID:Fo2Np7TJ
https://oraclesqlpuzzle.ninja-web.net/regex/regex-2-30.html
これは解読無理やろw 課題→正規表現を思いつくことはできるかも知れんが
正規表現→課題の解読は不可能に近い

課題:行ごとで、
文字列CABと
文字列ABCのみの行を検索する。

^((C(?=AB))|((?<=C)A(?=B))|((?<=CA)B)
|(A(?=BC))|((?<=A)B(?=C))|((?<=AB)C))*$
2021/03/07(日) 23:05:17.93ID:6FoXMbth
>>545
^(?:CABC?|ABC(?:AB)?)+$

でよくない?
2021/03/07(日) 23:21:37.42ID:Fo2Np7TJ
それで同じ結果になるな regex 101 でやると
2021/03/07(日) 23:53:47.53ID:4bEjyVwB
正規表現には「必ず」コメントが欲しいな
できれば例も
典型例と境界例も
549デフォルトの名無しさん
垢版 |
2021/03/11(木) 21:40:27.72ID:RBQB718T
お願いします
●Regular Expressionの使用環境
JavaScript

●検索か置換か?
置換

●説明
数字の文字列の間の1個以上の空白や改行を カンマで置換して繋げたい

33034640, 33034640, 21703214
●対象データ
33034640 30203225

21703214
2021/03/11(木) 22:14:06.84ID:IDj18sQF
>>549
¥s+をカンマで置換
2021/03/11(木) 22:15:56.92ID:IDj18sQF
https://regex101.com/r/h90Hqy/1
2021/03/11(木) 22:29:51.41ID:79QhYvaG
前後の数字チェック入り(区切りに\t,\fを除く)
(JavaScriptって言ってもWSH(JScript)や古いとダメ)
text.replace(/(?<=\d)[ \r\n]+(?=\d)/,", ")
2021/03/11(木) 22:30:57.72ID:79QhYvaG
text.replace(/(?<=\d)[ \r\n]+(?=\d)/g,", ")
554デフォルトの名無しさん
垢版 |
2021/03/11(木) 23:04:03.06ID:RBQB718T
>>550
それすると文頭や文末にあるスペースにもカンマがついて変になっちゃいます。
555デフォルトの名無しさん
垢版 |
2021/03/11(木) 23:08:30.44ID:RBQB718T
>>553
iPadのtextwellっていうアプリでやってるんですが・・・何故か動かないです
2021/03/11(木) 23:29:09.19ID:IDj18sQF
>>554
うーんなんだかなぁって感じだけど
look-behindが使えない環境ならキャプチャして上書きすればいいよ
https://regex101.com/r/ttVIeE/1
2021/03/11(木) 23:33:53.05ID:APoyxLpJ
文頭,文末のスペース,改行を残す必要がないなら先にtrimしちゃえば良いのでは
str.trim().replace(/\s+/gm, ',')
558デフォルトの名無しさん
垢版 |
2021/03/12(金) 07:31:49.43ID:/Ahlj9GN
>>557
できました!ありがとうございました!
2021/03/25(木) 17:05:14.58ID:m/0xUypz
浮動小数点数の仮数部の正規表現がたとえば
https://qiita.com/hitsumabushi845/items/1b1a4921d515f662b416
を見ると
([0-9]+(\.[0-9]*)?|\.[0-9]+)
とかなり煩雑な感じなんですが、これを[0-9]+と\.?のインターリービングとして表記できればより簡潔になるはずなのに、なぜ正規表現にインターリービングがないのか、ご存知の方いらっしゃいませんか?
2021/03/25(木) 18:34:43.45ID:T+HzAix1
インターリービングとは
2021/03/25(木) 18:35:20.79ID:iRaOTaqm
>>559
どういう意味?
[0-9.]+
っていうことか?
12.34.56
こういうものも拾うことになるけど
2021/03/25(木) 18:44:54.48ID:ItxHMUbH
正規表現でやるものなのかそれ?
2021/03/25(木) 20:05:19.84ID:DBtu6Q2L
0-9が1回以上、.が1回以下現れるパターンを簡潔に書ければいいんだよね
2021/03/25(木) 20:51:18.60ID:T+HzAix1
>>559
0.123とかだけでなく.123みたいな表記も含めてるから煩雑に見えるだけでしょ
2021/03/25(木) 20:57:31.28ID:+PvM3W0M
例えばpythonだと、

\d

と書くと、

[0-9]

と同じ意味になるんだが、その程度の省略ができるだけでは不満?
2021/03/26(金) 12:59:11.27ID:8UZMtFlJ
まず\dと[0-9]は一致しないケースがあるからダメでしょ

単なるバイトシーケンスとして扱っているときは \d == [0-9] だけど、
Unicodeの文字列として扱っているときはUnicodeのNdカテゴリに一致するかを見るので
\dが全角の「0」に一致したりする

Pythonもこういう仕様持ってた気がするけどちょっと最近触ってないから怪しい
2021/03/26(金) 13:48:50.07ID:9MjXQivW
([0-9]+(\.[0-9]*)?|\.[0-9]+)

なんかほかのものもマッチする
0.
0.0.0
https://regex101.com/r/MK7ZcW/
2021/03/26(金) 13:50:58.63ID:9HpPnfto
\dより\wで嵌ることが絶対多い(Unicodeの場合)
2021/03/26(金) 14:50:30.80ID:yQ1w8lx7
動きそうで動かないのは、\s\Sかな
改行かなにかで引っ掛からなくて困る事がある
2021/03/26(金) 19:09:23.59ID:bWZQxU2M
>>567
部分列にマッチしたんだろうな
2021/03/27(土) 07:24:19.21ID:6HYRQzqn
>>567
0. にマッチするのは仕様通り
0.0.0 にマッチしてるのはグローバルフラグを付けるてるから 0.0 と .0 にマッチしてる
外せばマッチしないよ
2021/03/27(土) 07:53:26.38ID:c8B2TB9l
>>571
.0にマッチするのは正しいんじゃないの?
要らないなら[0-9]+(\.[0-9]*)?で済むでしょ
2021/03/27(土) 07:59:48.48ID:HYD5C7Ts
数値として正しくないものの一部にマッチするのがいやなんだろ
そりゃ前後の条件を指定してないからマッチするのは当然なんだから
(?<![0-9.])と(?![0-9.])を前後につけりゃ弾けるよ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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