[英]Don't replace regex if it is enclosed by a character
我想,以取代由封閉所有字符串-
成封閉琴弦~
,但如果此字符串再次被封閉*
。
舉個例子,這個字符串......
The -quick- *brown -f-ox* jumps.
......應該成為......
The ~quick~ *brown -f-ox* jumps.
我們看到-
只有在不在 *<here>*
范圍內時才會被替換。
我現在的javascript-regex(不管它是否被*
括起來都不關心):
var message = source.replace(/-(.[^-]+?)-/g, "~$1~");
編輯:請注意,可能存在奇數個*
s的情況。
這與正則表達式有點棘手。 我想我會做的是這樣的:
var msg = source.replace(/(-[^-]+-|\*[^*]+\*)/g, function(_, grp) {
return grp[0] === '-' ? grp.replace(/^-(.*)-$/, "~$1~") : grp;
});
這看起來對於任何一個 -
或*
組,只執行對那些虛的更換。 通常,“嵌套”語法對正則表達式具有挑戰性(或不可能)。 (當然,作為對問題說明的評論,有一些特殊情況 - 懸掛元字符 - 這也使這一點復雜化。)
我會通過基於*
拆分數組然后只替換偶數索引來解決它。 匹配不平衡的星星比較棘手,它涉及知道最后一個項目索引是奇數還是偶數:
'The -quick- *brown -f-ox* jumps.'
.split('*')
.map(function(item, index, arr) {
if (index % 2) {
if (index < arr.length - 1) {
return item; // balanced
}
// not balanced
item = '*' + item;
}
return item.replace(/\-([^-]+)\-/, '~$1~');
})
.join('');
找出匹配是否未被某些分隔符包圍是一項非常復雜的任務 - 請參閱此示例 。 Lookaround可能有所幫助,但JS只支持前瞻。 所以我們可以將“ 不被~
包圍 ”重寫為“ 后跟偶數或~
”,並匹配:
source.replace(/-([^-]+)-(?=[^~]*([^~]*~[^~]*~)*$)/g, "~$1~");
但是我們更好地匹配-
和*
,以便我們消耗包含在*
s中的任何東西,然后可以在回調函數中決定不替換它:
source.replace(/-([^-]+)-|\*([^*]+)\*/g, function(m, hyp) {
if (hyp) // the first group has matched
return "~"+hyp+"~";
// else let the match be unchanged:
return m;
});
這樣做的好處是能夠更好地指定“ 封閉 ”,例如通過在“內部”添加字邊界,以更好地處理無效模式(例如@Maras提到的奇數*字符) - 當前的正則表達式只是采取接下來的兩次出場。
傑克的一個非常明確的答案。
source.split(/(\*[^*]*\*)/g).map(function(x,i){
return i%2?x:x.replace(/-/g,'~');
}).join('');
似乎工作,干杯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.