我正在从格式化的字符串中读取信息。 格式如下:
"foo:bar:beer:123::lol"
“:”之间的所有内容都是我想用正则表达式提取的数据。如果a:后跟另一个:(如“::”),则该数据必须为“”(空字符串)。
目前我用这个正则表达式解析它:
(.*?)(:|$)
现在我想到了数据中也可能存在“:”。所以它必须被逃脱。 例如:
"foo:bar:beer:\::1337"
如何更改正则表达式以使其与“\:”匹配作为数据呢?
编辑:我使用JavaScript作为编程语言。它似乎对复杂的规则表达有一些限制。解决方案也应该在JavaScript中运行。
谢谢, 麦克法兰
答案 0 :(得分: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中缺少lookbehind断言)。
<强>解释强>
( # 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
答案 1 :(得分:2)
使用负面的lookbehind断言。
(.*?)((?<!\\):|$)
如果:
之前的不是,则只会匹配\
。
答案 2 :(得分:1)
这是一个解决方案:
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
仍为\a
)以下是字符串b
的示例,该字符串应提供以下令牌:\n
,<empty string>
,\
,:
,{{1} },x
,>>> tokenize("\\a:b:\\n::\\\\:\\::x");
["\a", "b", "\n", "", "\", ":", "x"]
。
\
为了更清楚:放入标记器的字符串将被解释,它有2个特殊字符::
和\
\
只有在:
或:
后面才会有特殊含义,并且会有效地“逃避”这些字符:这意味着它们将失去对tokenizer的特殊含义,并且它们将被视为任何正常角色(因此将成为令牌的一部分)。我意识到OP没有要求斜线转义,但其他观众可能需要一个完整的解析库来允许数据中的任何字符。