正则表达式用于解析带有转义字符的字符串

regex to parse string with escaped characters

本文关键字:转义字符 字符串 用于 正则表达式      更新时间:2023-09-26

我正在从格式化字符串中读取信息。格式如下所示:

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

":"之间的一切都是我想用正则表达式提取的数据。如果 : 后跟另一个 :(如 "::"),则此数据必须是 "(空字符串)。

目前我正在用这个正则表达式解析它:

(.*?)(:|$)

现在我想到":"也可能存在于数据中。所以它必须被逃脱。例:

"foo:bar:beer:'::1337"

如何更改我的正则表达式,使其也与"'':"作为数据匹配?

编辑:我正在使用JavaScript作为编程语言。它似乎对复杂的调节表达式有一些限制。该解决方案也应该在JavaScript中工作。

谢谢麦克法兰

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

这是一个解决方案:

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;
}

它根据:字符将字符串拆分为标记。

  • 但是,如果您希望:字符成为令牌的一部分,则可以使用'对其进行转义。
  • 如果您希望'成为令牌的一部分,则可以使用 ' 对其进行转义
  • 任何其他
  • '都不会被解释。(即:'a仍然'a
  • 因此,您可以将任何数据放入令牌中,前提是事先正确格式化数据。

下面是一个字符串 'a:b:'n::'':'::x 的示例,它应该给出这些标记:'ab'n<empty string>':x

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

为了更清楚:放入分词器的字符串将被解释,它有 2 个特殊字符:':

  • 只有当后面跟着':时,'才会具有特殊的含义,并且会有效地"转义"这些字符:这意味着它们将失去它们对分词器的特殊含义,并且它们将被视为任何正常字符(因此将成为令牌的一部分)。
  • :是分隔 2 个令牌的标记。

我意识到 OP 没有要求斜杠转义,但其他查看器可能需要一个完整的解析库,允许数据中的任何字符。

使用否定的后视断言。

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

这只有在前面没有'的情况下才会匹配: