回答:
解決策は、前後のテキストのキャプチャを追加することです。
str.replace(/(.*name="\w+)(\d+)(\w+".*)/, "$1!NEW_ID!$3")
$
ため、最初の単語(\w+)
はグループになり$1
、中央の部分(\d+)
は2番目のグループになります(ただし、置換では無視されます)、3番目のグループは$3
です。したがって、の置換文字列を指定する"$1!new_ID!$3"
と、$ 1と$ 3は自動的に最初のグループと3番目のグループに置き換えられ、2番目のグループを新しい文字列に置き換えて、周囲のテキストを維持します。
Javascriptが(ES2018の時点で)後読みを持つようになったため、新しい環境では、このような状況ではグループを完全に回避できます。むしろ、キャプチャしているグループの前に来るものを後読みし、先読みを後にし、単に !NEW_ID!
次のものに置き換えます。
const str = 'name="some_text_0_some_text"';
console.log(
str.replace(/(?<=name="\w+)\d+(?=\w+")/, '!NEW_ID!')
);
この方法では、完全一致は交換が必要な部分のみです。
(?<=name="\w+)
-の後読みname"
、その後に単語文字(幸いなことに、後読みはJavascriptで固定幅である必要はありません!)\d+
-1つ以上の数字に一致-ルックアラウンドにないパターンの一部のみ、結果の一致に含まれる文字列の一部のみ(?=\w+")
-単語文字の先に"
`を付けて後読みはかなり新しいことを覚えておいてください。最新バージョンのV8(Chrome、Opera、Nodeを含む)で動作しますが、少なくとも他のほとんどの環境では動作しません。したがって、Nodeと独自のブラウザー(最新バージョンのV8で実行されている場合)で後読みを確実に使用できますが、ランダムクライアント(パブリックWebサイトなど)ではまだ十分にサポートされていません。
\d+
ね?
match => match * 2
ます。2番目のパラメーターをに置き換えます。数字はまだ全体の試合なので、グループのための必要はありません
マシューの答えを少し改善するには、最後のキャプチャグループの代わりに先読みをすることができます。
.replace(/(\w+)(\d+)(?=\w+)/, "$1!NEW_ID!");
または、10進数で分割して、次のように新しいIDで結合することもできます。
.split(/\d+/).join("!NEW_ID!");
例/ここのベンチマーク:https : //codepen.io/jogai/full/oyNXBX
2つのキャプチャグループを使用することも可能でした。数字の前後に追加の左と右の境界として2つのダッシュを含めることもでき、変更後の式は次のようになります。
(.*name=".+_)\d+(_[^"]+".*)
const regex = /(.*name=".+_)\d+(_[^"]+".*)/g;
const str = `some_data_before name="some_text_0_some_text" and then some_data after`;
const subst = `$1!NEW_ID!$2`;
const result = str.replace(regex, subst);
console.log(result);
式を探索/簡略化/変更したい場合は、regex101.comの右上のパネルで説明されてい ます。必要に応じて、このリンクで、サンプル入力とどのように一致するかを確認することもできます。
jex.imは正規表現を視覚化します。
単純なオプションは、数字をキャプチャして置き換えるだけです。
const name = 'preceding_text_0_following_text';
const matcher = /(\d+)/;
// Replace with whatever you would like
const newName = name.replace(matcher, 'NEW_STUFF');
console.log("Full replace", newName);
// Perform work on the match and replace using a function
// In this case increment it using an arrow function
const incrementedName = name.replace(matcher, (match) => ++match);
console.log("Increment", incrementedName);