1

次の変換を行う正規表現を作成しようとしています。

  1. Apple Orange>AO
  2. Load Module>LM
  3. anApple Orange>O
  4. toLoad Module>M

適切なパターンを見つけましたが、奇妙な動作に気付きました。これが私の最初の試みです:

/^([A-Z])?[^ ]* ([A-Z])/

この式で 3 番目 (および 4 番目) のテスト ケースで置換を実行すると、驚くべき結果が得られます。

'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z])/,'$1$2')
> "Orange"

なぜそれは驚くべきことですか?文字列が大文字で始まっていないため、最初のグループは明らかに一致しませんが、2 番目のグループは単一の大文字のみを選択します: ([A-Z])、その後のすべてではありません:([A-Z].*)

驚いたことに、.*最後のキャプチャ グループの直後に追加すると、正しい結果が得られました。

'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z]).*/,'$1$2')
> "O"

なぜこれが起こっているのかは、JS と正規表現についての私の理解を超えています。どのような種類の闇の魔法が単一の文字[A-Z]を複数の文字や小文字の文字でさえも返すのかを知ることに興奮しています。

実行可能なデモは次のとおりです。

var testCases = [
      'Apple Orange',
      'Load Module',
      'anApple Orange',
      'toLoad Module'
    ],
    badregex = /^([A-Z])?[^ ]* ([A-Z])/,
    goodregex = /^([A-Z])?[^ ]* ([A-Z]).*/;

document.onreadystatechange = function(n){
  if (document.readyState === "complete"){
      for (var i=0,l=testCases.length; i<l; i++){
        var p = document.createElement('p'),
            testCase = testCases[i];
        p.innerHTML = ""+testCase+" &gt; "+testCase.replace(badregex,'$1$2')
        document.body.appendChild(p);
      }
      document.body.appendChild(document.createElement('hr'));
      for (var i=0,l=testCases.length; i<l; i++){
        var p = document.createElement('p'),
            testCase = testCases[i];
        p.innerHTML = ""+testCase+" &gt; "+testCase.replace(goodregex,'$1$2')
        document.body.appendChild(p);
      }
  }
}

4

3 に答える 3

2

私はしたい、

> "Apple Orange".replace(/(?:^|\s)([A-Z])|./g, "$1")
'AO'

物事を複雑にしないでください。スペースの直後または先頭にあるすべての大文字をキャプチャするだけです。そして、残りのすべての文字を一致させます。一致したすべての文字を に置き換えます$1。一致したすべての文字は、置換部分内に存在する文字に置き換えられることに注意してください。

デモ

なんで?

'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z])/,'$1$2')
> "Orange"
  • ([A-Z])?先頭にオプションの大文字があるかどうかをチェックします。そのようなことはない。したがって、空の文字列をキャプチャします。
  • [^ ]*0 個以上の非スペース文字に一致します。
  • <space>スペースに一致します。
  • ([A-Z])オレンジ色の最初の文字のみをキャプチャします。
  • 一致したすべての文字を- $1> 空の文字列$2->に置き換えると、OOrange
于 2015-06-09T18:55:33.230 に答える
1

最初の例は に一致しanApple Oます。 はオプションであり、一致しない$1ため空です。したがって、文字列内で に 置き換える と、次のようになります。^([A-Z])?$2OanApple OOanApple OrangeOrange

于 2015-06-09T19:00:45.650 に答える
1

複雑な正規表現を使用する代わりに、replace非常に単純な正規表現をmatch使用joinして、目的の出力を得ることができます。

'anApple Orange'.match(/\b([A-Z])/g).join('')
//=> O

'Apple Orange'.match(/\b([A-Z])/g).join('')
//=> AO
于 2015-06-09T19:12:06.913 に答える