質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

5235閲覧

正規表現で「ちょうど1回の繰り返し」

stringthread

総合スコア19

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2019/04/07 11:12

正規表現で「ちょうど1回のみ繰り返す」文字列の指定方法を教えてください。例えば、「abc&def」の「&de」とはマッチするが、「abc&&de」は「&&de」とも「&de」ともマッチしない、というような形です。エスケープシーケンスに近い処理で、「\n」には置換をするが「\n」にはしないというようなものを実装しようと考えています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

/(?<!&)&de/

ですね。「否定戻り読み」と言います。ただし、使えるエンジンと使えないエンジンがあるので注意してください。Web ブラウザで動作する JavaScript は無理ですね。


【追記】

エスケープシーケンスを実装するのであれば、**「エスケープシーケンスのエスケープ表現に予めマッチさせる」**のが正解だと思います。例えば % をエスケープシーケンスにするのであれば

/(%%)|(%foo)|(%bar)/

といったような感じです。どれがマッチしたのかはキャプチャ結果で取れるので、それで何に置換するかを分岐します。

もし最初の方針だと %%%foo にもマッチしなくなってしまうので、方針としてはこちらのほうが正しいです。

js

1"消費税率10%%%boldマジでつらい%endbold".replace(/(%%)|(%bold)|(%endbold)/g, (str, ...m) => { 2 if (m[0]) { 3 return '%' 4 } 5 if (m[1]) { 6 return '<b>' 7 } 8 if (m[2]) { 9 return '</b>' 10 } 11 return str 12})

投稿2019/04/07 11:16

編集2019/04/07 12:40
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

stringthread

2019/04/07 11:24

ありがとうございます。そんな機能があるんですね。今回はJSで使うことを予定していたので残念ながら使えませんが、勉強になりました。
mpyw

2019/04/07 12:12

追記をご確認ください
stringthread

2019/04/07 14:05

たしかに、このアプローチは理想的に見えますね。 これは正規表現というよりJavaScriptの言語仕様に絡む疑問かもしれませんが、"%%%bold"は"%<b>"になって欲しいところで、正規表現を繰り返し適用するのでは、"%%%bold"->"%%bold"->"%bold"->"<b>"になってしまうように思えます。回答してくださったコードでは、そのようなことにはならないのでしょうか。
mpyw

2019/04/07 16:39

同一の正規表現パターンに含める限りはならないです。パターンを分けてJavaScriptレベルで複数回適用するとなってしまいます。なので必ず1回で済ませるようにしましょう。正規表現が長くなってしまってつらかったら `new RegExp()` のほうを使って文字列から組み立てましょう
mpyw

2019/04/07 16:43 編集

ちなみにこれは言語を問わずそうなります。基本的にマッチした部分まで文字列を消化して、そのオフセットから次のマッチングを再開する、という動きになります。(ただし、「^」「$」「先読み」「戻り読み」などは例外的に文字列を一切消化しません)
stringthread

2019/04/08 13:59

なるほど、一つのパターンで済ませれば大丈夫なんですね。ありがとうございました。
guest

0

今回はJSで使う

マッチする、しない、でいうと、否定後読み機能が無いと無理ですが、置換であればやりようがあります。

JavaScript

1"文字列".replace(/([^&]|^)&de/,"$1置換文字列")

投稿2019/04/07 12:17

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

stringthread

2019/04/07 13:58

なるほど、確かに直前の字をキャプチャで取って置換後の先頭につければ、処理結果としては欲しいものになりますね。盲点でした。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問