6

フォーマットされた文字列から情報を読み取っています。フォーマットは次のようになります。

"foo:bar:beer:123::lol"

「:」の間はすべて正規表現で抽出したいデータです。: の後に別の : ("::" など) が続く場合、このデータは "" (空の文字列) である必要があります。

現在、私はこの正規表現でそれを解析しています:

(.*?)(:|$)

ここで、「:」がデータ内にも存在する可能性があることに気付きました。したがって、エスケープする必要があります。例:

"foo:bar:beer:\::1337"

「\:」もデータとして一致するように正規表現を変更するにはどうすればよいですか?

編集: JavaScript をプログラミング言語として使用しています。複雑な正規表現に関しては、いくつかの制限があるようです。このソリューションは、JavaScript でも機能するはずです。

ありがとう、マクファーレン

4

3 に答える 3

3
var myregexp = /((?:\\.|[^\\:])*)(?::|$)/g;
var match = myregexp.exec(subject);
while (match != null) {
    for (var i = 0; i < match.length; i++) {
        // Add match[1] to the list of matches
    }
    match = myregexp.exec(subject);
}

入力:"foo:bar:beer:\\:::1337"

出力:["foo", "bar", "beer", "\\:", "", "1337", ""]

最後の一致として常に空の文字列を取得します。空の文字列も区切り文字間で一致させる必要があるという要件(およびJavaScriptでの後読みアサーションの欠如)を考えると、これは避けられません。

説明:

(          # Match and capture:
 (?:       # Either match...
  \\.      # an escaped character
 |         # or
  [^\\:]   # any character except backslash or colon
 )*        # zero or more times
)          # End of capturing group
(?::|$)    # Match (but don't capture) a colon or end-of-string
于 2012-04-18T12:15:16.637 に答える
3

解決策は次のとおりです。

function tokenize(str) {
  var reg = /((\\.|[^\\:])*)/g;
  var array = [];
  while(reg.lastIndex < str.length) {
    match = reg.exec(str);
    array.push(match[0].replace(/\\(\\|:)/g, "$1"));
    reg.lastIndex++;
  }
  return array;
}

文字に応じて文字列をトークンに分割します:

  • ただし、トークンの一部にしたい場合は、:文字をエスケープできます。\
  • トークンの一部にしたい場合は、 \withをエスケープできます\
  • それ以外\は解釈されません。(つまり:\a残ります\a)
  • そのため、データが事前に正しくフォーマットされていれば、任意のデータをトークンに入れることができます。

以下は、\a:b:\n::\\:\::xこれらのトークンを与える文字列の例です: \a, b, \n, <empty string>, \, .:x

>>> tokenize("\\a:b:\\n::\\\\:\\::x");
["\a", "b", "\n", "", "\", ":", "x"]

より明確にするために、トークナイザーに入れられた文字列が解釈され、2 つの特殊文字が含まれます\:

  • \\またはが続く場合にのみ特別な意味を持ち、:これらの文字を効果的に「エスケープ」します。つまり、トークナイザーの特別な意味を失い、通常の文字と見なされます (したがって、トークンの一部になります)。 )。
  • :2 つのトークンを区切るマーカーです。

OPはスラッシュエスケープを要求しなかったことに気づきましたが、他のビューアーはデータ内の任意の文字を許可する完全な解析ライブラリを必要とする可能性があります.

于 2013-11-19T14:03:44.890 に答える
2

否定の後読みアサーションを使用します。

(.*?)((?<!\\):|$)

が前に付いていない:場合にのみ一致します。\

于 2012-04-18T11:50:31.807 に答える