Regular Expression(正規表現) Part15
■ このスレッドは過去ログ倉庫に格納されています
Regular Expressionスレです。 質問する場合は必ず実装言語や処理系ソフトウェア名を示してください。 前スレ Regular Expression(正規表現) Part14 https://mevius.5ch.net/test/read.cgi/tech/1489511075/ 次スレは>>980 宜しく 天ぷら等>>2 以降 ●Regular Expressionの使用環境 サクラエディタ ●検索か置換か? 置換 ●説明 空白を除去するのに\sで検索してますが アルファベットの文字間では空白を残したい ●対象データ ジャッキー チェン:Jackie Chan ●希望する結果 ジャッキーチェン:Jackie Chan スペースの直前直後が[a-zA-Z]ならマッチせず それ以外ならマッチするという正規表現でいいのかな? もうちょっと仕様を詰めたほうがいい気がする John Paul IIの2つ目のスペースは削除? George W. Bushの2つ目のスペースは削除? (?<=[^A-Za-z])\s(?=[^A-Za-z])|(?<=[^A-Za-z])\s(?=[A-Za-z])|(?<=[A-Za-z])\s(?=[^A-Za-z]) >>369 スペースの前後ともアルファベットならマッチせず、それ以外ならマッチするです。 その他の条件はありません。ちなみに行頭と行末のスペースにはマッチさせたいです。 >>370 ありがとうございます。行頭が残るようですが希望のことができました。 >>371 ^\s++|\s++$|(?<=[^A-Za-z])\s(?=[^A-Za-z])|(?<=[^A-Za-z])\s(?=[A-Za-z])|(?<=[A-Za-z])\s(?=[^A-Za-z]) ORでは1つで良いような (?<![a-zA-Z])¥s|¥s(?![a-zA-Z]) ゼロ個でも \s(?!(?<=[A-Za-z].)(?=[A-Za-z])) >>374 へぇーー 速度的にも有利っぽいしこのパターン覚えとくわ \s(?!(?<=[A-Za-z].)[A-Za-z]) 肯定先読み要らないよね。ある方が見やすい気がしなくもないけど 374の「選択子がゼロ個」と「集合の否定」の話じゃなければアサーションを入れ子にする必要もないのですよ \s(?>(?![A-Za-z])|(?<![A-Za-z].)) ●使用環境 RegEx Lab(iOSアプリ,ICU Regex) iOSショートカットアプリ ●検索か置換か? 検索 ●説明 以下の2パターンのデータから"あいうえお"を取り出す正規表現を教えてください。 自分なりに考えたのですが↓ではうまくいきませんでした。 名前(?::<.+?>|:)(.*?)(?:</a>|$) ちなみにCotEditorでは↑の正規表現でも検索できました。 ●対象データ1 〜 <div class="abcde_abcde"> 名前:あいうえお </div><!--abcde_abcde--> 〜 ●対象データ2 〜 <div class="abcde_abcde"> 名前:<a href="https://www.google.com" ;>あいうえお</a> </div><!--abcde_abcde--> 〜 ●希望する結果 あいうえお >>379 $が行末にマッチしてないだけなら、単に改行\Rに置き換えてみてもいいし正規表現の頭におまじない(?m)を足してみてもいい 置換じゃなくて検索なら (?<=名前:<[^>]{0,99}?>).*?(?=</a>)|(?<=名前:)(?!<).*+ >>380 >>381 こんなに色々なやり方があるんですね……勉強になります。 無事検索できるようになり本当に助かりました。 ありがとうございました! grepのperl正規表現オプションを使ってURLのホスト名を抽出したいです https://mevius.5ch.net/test/read.cgi/tech/1568640311/l50 http://www.google.co.jp/ このスレだったら”mevius” googleなら”www” 「https:// 」or「http:// 」と「.」に挟まれた文字列の最短一致でできそうなのですがなぜか上手くいきません 1文字に挟まれたパターンは検索して出てくるのですが、複数文字に挟まれたパターンはあまり出てこなくて、この際はっきりしたいので「〇〇〇と△△△に挟まれた文字列の中身のみを最短一致で抽出」パターンも教えてください >>383 /https?:\/\/([^./]+)/ grepもperlも知らないけどこんな感じでどうや △△△が一文字なら△を含まない文字の連続で取るといいと思う 複数文字の場合は知らない >>384 早速ありがとうございます ですがそのやり方ですとgrepでは抽出できませんでした △△△は複数の種類の文字ですね言葉足らずでした 正しくは「ABC」と「DEF」に挟まれた文字みたいなものですね >>386 できなかったか、すまん これは自分には無理だわ 知識もないのにでしゃばるべきじゃなかったな pcregrepならキャプチャグループを番号指定して出力可能 $ pcregrep -o1 ':\/\/(.+?)\.' input.txt >>388 いえいえ >>387 >>389 おー、これでできました pcregrepのやり方もありがとうございます Javaで setMethod(); getMethod(); setBake(); みたいなgetter,setterは検出したくなく、 Methoda(); Methodb(); bake(); みたいなset, getで始まっていない()付きの文字列を含む 行を正規表現一行で検出するするのはどうしたらいいのですか? ^(?=.*?\b(?!set|get)[A-Za-z]++\(\);).* ^(?=.*\b(?!set|get)[A-Za-z]+\(\);).* 申し訳ありません。 Methoda() { Methodb(){ c = z.Methoda().Methodb(a,b) みたいな行は検索の対象にいれたいのですが よろしくお願いします。 もうちょい目的と仕様をはっきりさせたほうがいいんじゃない? get/setではじまってない()付きの文字列を含む行なら問題ないけど get/setではじまってないメソッド定義やメソッド呼び出しをもれなく抽出したいということなら 正規表現だときつい気がする 後者ならコードをパースして使ってるメソッド一覧を出力するようなツールを探したほうがいいかも ^(?=.*?\b(?!set|get)[A-Za-z]++\(\)).* (?<=(?:\n|^|\.))(?<!set|get)[a-zA-Z]+\( 引数が無い and setter, getterではないメソッドを含んでいる行です ひょっとして正規表現内では表現できないかもしれません。 文脈自由レベルでしょうか? 5chのスレタイはこん感じで入っている <a href="1599110613/l50">1: ぶっちゃけ始めるのにいい言語て何 part3 (78)</a> <a href="1545032904/l50">2: 文字コード総合スレ Part12 (95)</a> <a href="1598112455/l50">3: Rust part9 (198)</a> <a href="1598336253/l50">4: 小6におすすめな言語 (32)</a> <a href="1594528940/l50">5: C++相談室 part152 (404)</a> <a href="1596690797/l50">6: Xamarin Part7 (97)</a> <a href="1598527450/l50">7: くだすれPython(超初心者用) その50【まず1嫁】 (423)</a> ここからたとえば「言語」とついたスレタイだけ抽出するのは無理だった <a href="1599110613/l50">1: ぶっちゃけ始めるのにいい言語て何 part3 (78)</a> <a href="1598336253/l50">4: 小6におすすめな言語 (32)</a> >>397 いやもう \b(?!set|get)\w+\(\) でいいんでしょ JavaScript では、これで複数行マッチ(g)できた /<a[^>]+>.*言語.*<\/a>/g <a で始まって、> 以外の文字が、1文字以上続いて、> 言語の前後に、.* <\/a> で終わる 他には、Ruby でスクレイピングすれば? >>400 おかしいな、それでうまくいかなかったのに と思ったら入ってくるHTMLソースに改行がないようだ </a>のあとに改行入れるとうまくいくように見えるけど、HTMLソースがおかしくなる 正規表現以前の問題だったわ 別に抜き出すだけなら、 一旦、</a> の後ろに、改行を追加してから、正規表現を使えば? それか、HTML をコピーしてから、やるとか "/(<a(?>[^>]+)>(?>[^<]*?言語[^<]*)<\/a>)(?:<a(?![^<]*言語)(?>[^<]+)<\/a>)*/$1/g" "/<a(?![^<]*言語)(?>[^<]+)<\/a>//g" Ruby, Nokogiri で、スクレイピングしたら、 require 'open-uri' require 'nokogiri' # プログラム技術@スレッド一覧 url = "https://mevius.5ch.net/tech/subback.html" ; doc = Nokogiri::HTML( open( url ) ) # 「言語」という単語が含まれる、タイトルを表示する ary = doc.css( "#trad > a" ).map { |elem| elem.content } .select { |title| title.include? "言語" } puts ary 出力 6: 次世代言語21 Go Nim Rust Swift Kotlin TypeScript (330) 10: 日本語プログラミング言語『なでしこ』スレ6.1c2ch.net (108) 以下略 冗談抜きでそんな無駄な努力するよりxpathとかそっち系おすすめするぞ 単純なスクレイピングはcurl+pupが楽 $ curl -s https://mevius.5ch.net/tech/subback.html | pup '#trad > a' text{} | grep 言語 | head -5 >>405 のopen-uri を、下のように、外部コマンドのcurl にも出来るけど、 普通は、わざわざ外部コマンドを呼ばない url = "http〜" doc = Nokogiri::HTML( open( url ) ) html = `curl http〜` doc = Nokogiri::HTML( html ) ●Regular Expressionの使用環境 サクラエディタ ●検索か置換か? 置換 ●説明 httpを含まない行の/を年に置き換えたい ●対象データ https://5ch.net/ 2020/9 ●希望する結果 https://5ch.net/ 2020年9 こんなもんでもよろしいでしょうか。 あんまりうまくないと思いますが。 よろしくお願いいたします。 置換前 ^(?!http)([0-9]{4})(/) 置換後 $1年 >>410 ありがとうございます。うまくいきました。 >>403 >>404 なんかすげえな >>402 ,405-408 いろいろやり方あるんだね、サンクス ●Regular Expressionの使用環境 Linux awkとか、sed。 目的が置換なので、コマンドはなんでも構いません。 ●検索か置換か? 置換 ●説明 = 任意の文字列 : を置き換えたい ※前後に半角スペースあり。 ●対象データ hogeghoe = type: furagura mogemoge = syntax: mojamoja ●希望する結果 hogeghoe type: furagura mogemoge syntax: mojamoja ※スペースで置き換えた例 よろしくお願いいたします。 >>413 取り消します。精査する前に書き込んでおり 間違いがございました。すいません。 ●Regular Expressionの使用環境 Linux awkとか、sed。 目的が置換なので、コマンドはなんでも構いません。 ●検索か置換か? 置換 ●説明 = 任意の文字列 : を置き換えたい ※前後に半角スペースあり。 ●対象データ hogeghoe = type: fuga:fuga mogemoge = syntax: moja:moja ※置換目的のコロンの後ろにさらにコロンがある場合があります。 =から「次の最初のコロン」までが置換対象です。 ●希望する結果 hogeghoe fuga:fuga mogemoge moja:moja ※スペースで置き換えた例 よろしくお願いいたします。 >>414 sed 's/ =[^:]*://g' >>415 ありがとうございます。理解を超えた書き方なので そのまま利用いたします・・・ >>416 そんなに難解ではないぞ : でない文字が0個以上続いて その後に一文字だけ : があるパターンを すべてスペースに書き換えるというだけの意味 ●使用環境:RegEx Lab(iOSアプリ,ICU Regex) ●検索か置換か?:検索 ●説明:時間毎の内容を取り出したいです。自分でも考えてみたのですが、(?m)(?<=\d{1,2}:\d{2}\r)([\s\S]*?)\r ではAt〜Mediaまで取得できませんでした。 補足として、各内容の前後には必ず時間と空白行が挿入されています。ただし、テキストにも空白行が挿入されている場合があります。ちなみに日付毎にファイルが分かれているため、対象データ最上部の日付が途中に挿入されることはありません。 ●対象データ 25 September 2020 ================= 8:05 テキスト1 10:44 テキスト2 At: スポット名: 位置情報・座標 Tags: タグ1, タグ2 Media: 123abcdefg.jpg Media: hijklmn456.png ●希望する結果 ○マッチ1 テキスト1 ○マッチ2 テキスト2 At: スポット名: 位置情報・座標 Tags: タグ1, タグ2 Media: 123abcdefg.jpg Media: hijklmn456.png とりあえず鬼雲なら \d\d?:\d\d\n(([^\n]+\n)+) で\1なり$1なりで取り出せるけど どー使うのかしらねーけど改行に続く時刻消せばいいんじゃねw \d\d?:\d\d\n\K((.(?!^\d\d?:\d\d))+\n)+ マッチに時間の直前の空行まで含めるのか?含まないのか? テキスト終端(例だとテキスト1\n 456.png\n)の改行文字を含めるのか?含まないのか? マッチがどこまでなのか曖昧 2段階になるけど一旦時刻をテキスト中に現れない文字に置換すれば簡単に出来る ^\d\d?:\d\d → ★ [^★]+ 時刻の直前の空行を含まないのなら \n\d\d?:\d\d → ★ テキスト終端の改行を(ry \n\n\d\d?:\d\d → ★ >>419 >>420 ありがとうございます! 試してみたところ、Meryでは問題なく動作しているようでしたがRegEx Labでは動作しませんでした… > 時間の直前の空行 >テキスト終端(例だとテキスト1\n 456.png\n)の改行文字 どちらも含めずに取得したいです。 (?m)(?<=^\d{1,2}:\d{2}(?:\r\n|(?<!\r)\n|\r(?!\n)))^[\s\S]*?(?=(?:\r\n|(?<!\r)\n|\r(?!\n))+\d{1,2}:\d{2}(?:\r\n|(?<!\r)\n|\r(?!\n))|(?:\r\n|(?<!\r)\n|\r(?!\n))*\z) これでよかったっぽい (?m)(?<=^\d{1,2}:\d{2}(?:\r?\n|\r))^[\s\S]*?(?=(?:\r?\n|\r)+\d{1,2}:\d{2}(?:\r?\n|\r)|(?:\r?\n|\r)*\z) >>423 どうだろうね、基本的な構造は>>418 と同じだけど データの改行コードがどうなっているのか謎だったのでとりあえず全種類対応しようと欲張ったらこんなことに \n に置き換えるとこう (?m)(?<=^\d{1,2}:\d{2}\n)^[\s\S]*?(?=\n+\d{1,2}:\d{2}\n|\n*\z) 長い短いではなく、試行回数が多い記述(行ったり戻ったり何度もやり直すもの)が遅い そういうのは逆に記述を詳しくしたりして長くするほうが速い >>424 問題なく動作しました、ありがとうございます! 本当に助かりました! >>416 正規表現のデフォルトは、貪欲・greedy・最長一致だから、 非貪欲・reluctant・最短一致にしたい場合に使う。? と同じ [^x]*、x以外の文字を、0個以上 [^x]+、x以外の文字を、1個以上 Ruby では、 src = "12x34x56" p src[ /.*x/ ] #=> 12x34x p src[ /.*?x/ ] #=> 12x p src[ /[^x]*x/ ] #=> 12x \d{1,2}なら\d\d? \d{2}なら\d\d の方が短く済むから2桁以下なら無駄 それは見易さと短さのどちらを優先するかによる 短いだけが正義では無い 2つ程度で見易いもクソも…と思うかも知れないが慣れない者にとっては数字の方が見易いらしい 俺は断然\d\d?派だが でもこれは(?:\r?\n|\r)→(?:\r\n?|\n) 同じ意味だが \r \r\n \n をどう表すか?ってことだから後者のように前方を固定した方が分かり易いと思う RtoLが関係してたりするのだろうか? 今どき\rだけとか見ないし\r?\nで良くね? 駄目? ●Regular Expressionの使用環境 c# .net Framework 4.8 ●検索か置換か? 検索 ●説明 「,」区切りの2桁の文字列を全て取得したい(Split関数でなく)。 ●対象データ 04,05,28 ●希望する結果 04 05 28 ●補足 現在使っている正規表現は右です (\d{2})(?:,(\d{2}))* これを使うと、対象となる2桁の数字のうち、最初と最後のものしか取得できません 対象データが4個以上でも同様です 以前 >>409 で質問し解答を頂いた者です。 内容は同じなんですが、この置換を他のパターンでも応用したく再度質問致します。 ●Regular Expressionの使用環境 サクラエディタ ●検索か置換か? 置換 ●説明 ◆を含まない行の▲を■に置き換えたい ◆▲■は任意の文字列で、文字数も決まっていません。 ●対象データ Sst68▲h4◆ DRkPP2▲V NN▲◆9K12XV▲ G▲RL88▲A7 ●希望する結果 Sst68▲h4◆ DRkPP2■V NN▲◆9K12XV▲ G■RL88■A7 どうぞよろしくお願いいたします。 >>437 返信ありがと だけど上手く取得できないです 対象データが 04,05,28 のときにマッチしたグループを全部出力すると 04, 04 となります >>438 MatchじゃなくてMatches使ってね よく考えたら単に¥d{2}でもよくない? >>436 ちっとも極端じゃないよ 対象テキストが長くて酷いと数sと数msとか何千倍、何万倍も差がつく もっと極端なことにもなって、だんまり(終わらない)状態になることもある あ、そのリンク先の表現でのことじゃなく一般的な話としてのことなので、念のため >>439 おかげさまで出来ました。ありがとうございます 数年前に某技術系Q&Aサイト全体が30分以上応答不能になったことがあったけど、アレもbacktrack絡みの正規表現処理(に高負荷をもたらす投稿)がトリガーだったはず Jane系のNGEx,ReplaceStr.txtの正規表現で酷いものが投稿されることがある よく吟味しないと 対象スレ(ちょっと長いスレとか)によってはだんまりとか発生する >>435 一旦、grep で、◆ を含まない行だけを抽出してから、処理すれば? grep -v "◆" ファイル名 バックトラックは対象が簡単に一致するものしか無いのであればそれほど気を使わなくても良いが 一致しないものがある場合 一致しない に至るまでに全パターンを試すから その挙動を必要最小限に抑えたものとそうでないものとでの試行数は桁違い 対象が長くなれば数倍どころでは済まない 大抵の場合、人が確認する際のロジックを再現するのが1番効率が良い NGEx.txtを晒すスレ7 http://jane2ch.net/test/read.cgi/community/1497272912/340 (<br>.*){20} 49194006ms 激重 ^(.*?<br>){20} *1570733ms ^(?:(?:(?!<br>).)*<br>){20} ****2202ms 軽い ^(?>.*?<br>){20} ****1784ms もっと軽い >>445 単なるテキストならいいのですが、用途としては リネーマーソフトReNamerやAdvanced Renamerなどで バッチ処理にも使いたいので。 >>435 (?:^(?!.*◆)|\G(?!\A))(.*?)▲ → $1■ >>448 出来ました!素晴らしいです!マジ感謝です!ありがとうございました。 一文字だけで改行するのを NGにするには どうしたらいい? oniguruma6.9.6 Windows10のVS2019で64bit版だとtestc.exeが無言で終了する、32bitだと正常。 Winodws7でVS2015U3だと64bitでも32bitでも正常に動作する。 これ、以前からWindows64bitが鬼門だなあ ●PowerShell ●置換 ●テキストファイル内の「WrtCookie=」で始まる行の値を「WrtCookie=」に置換する ●「WrtCookie=」で始まる行 現在のコマンド $input = '^(WrtCookie=).+$' $replacement = '$1' $file_contents = $(Get-Content $filepath) -replace $input, $replacement 結果 テキストファイル内の全行が出鱈目な文字列に置換されます たとえば「$1[$1W$1I$1N$1D$1O$1W$1]$1」など よろしくお願いします >>454 書き込む前にたくさんググりましたが、ダメでした >>453 俺のところじゃ、そのままでも正常だけどなあ(win7だからか? PS ver.5.1) その3行だけじゃあ表示も出力もされないので $file_contents を最後に追加した その入力ってJane系のiniファイル(SJIS)だよね? ファイルに出力もして確認してみた (デフォではUnicode16になっちゃうのでout-fileでencoding指定) Windows 10、PSVersion 5.1 では、 input という名前が、ダメ! >>456-458 おっしゃる通りに変数inputの名前を別の変数名にしたら出来ました inputは予約語みたいなものだったのね ありがとう VSCode を使っていれば、白色になる・注意されるから、おかしいとすぐに分かる まあ、echo などのエイリアスも、白くなるけど 質問 abc を a,b,c に一発で変換する正規表現を教えてください! 461じゃないけど、知らなかった。 行頭じゃない&行末じゃない だけ言えば字間全てに入れてくれるんだ。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる