9

-で囲まれているすべての文字列を で囲まれた文字列に置き換えたいのですが~、この文字列が再び で囲まれている場合はそうではありません*

例として、この文字列...

The -quick- *brown -f-ox* jumps.

...なるはず...

The ~quick~ *brown -f-ox* jumps.

内にない場合-にのみ置換されます。*<here>*

今のところ私のjavascript-regex(囲まれているかどうかは気にし*ません):

var message = source.replace(/-(.[^-]+?)-/g, "~$1~");

編集:奇数の*s がある場合があることに注意してください。

4

4 に答える 4

2

これは、正規表現で行うのは難しいことです。私がすることは次のようなことだと思います:

var msg = source.replace(/(-[^-]+-|\*[^*]+\*)/g, function(_, grp) {
  return grp[0] === '-' ? grp.replace(/^-(.*)-$/, "~$1~") : grp;
});

jsFiddle デモ

どちらか -またはグループを探し、*破線のものだけを置換します。一般に、「ネスト」構文は、正規表現では困難 (または不可能) です。(そしてもちろん、質問ノートへのコメントとして、これを複雑にする特殊なケース (ぶら下がっているメタ文字) もあります。)

于 2013-03-28T13:32:29.487 に答える
1

に基づいて配列を分割し*、偶数インデックスのみを置き換えることで解決します。バランスの取れていない星のマッチングはよりトリッキーで、最後の項目インデックスが奇数か偶数かを知る必要があります。

'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('');

デモ

于 2013-03-28T13:36:51.743 に答える
1

一致が区切り文字で囲まれていないかどうかを調べるのは、非常に複雑な作業です。この例も参照してください。ルックアラウンドは役に立ちますが、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 で言及されている奇数の * 文字) をより適切に処理できます。現在の正規表現は次の 2 つの出現を取ります。

于 2013-03-28T13:38:15.130 に答える
0

ジャックの非常に明確な答えの簡潔なバージョン。

source.split(/(\*[^*]*\*)/g).map(function(x,i){
return i%2?x:x.replace(/-/g,'~');
}).join('');

動作するようです、乾杯。

于 2013-03-28T16:43:04.257 に答える