我必须解析一些代表 URL 和描述的数据。
格式为
https://stackoverflow.com/questions/ask, Ask
(url, description
)。
由于 URL 中允许使用逗号,因此后端会用另一个逗号转义逗号(但仅限于 URL 部分)。
例如,以下输入字符串应解析为:
https://stackoverflow.com/questions/ask,, some weird path parts, Ask, with comma
https://stackoverflow.com/questions/ask, some weird path parts
Ask, with comma
我正在努力寻找如何在第一次出现未转义的
,
时分割字符串。
我的测试用例是
a,,b,, c, d, e,, f, ,, g
。我应该提取两个子字符串:a,b, c
和d, e,, f, ,, g
(描述部分不必转义逗号)。
我尝试使用正则表达式:
const input = 'a,, b,, c, d, e,, f';
const re = /(?<!,), /;
const parts = input.split(re);
console.log(parts, parts.length);
另一种尝试是使用非正则表达式解决方案:
const findUnescaped = (input: string): number => {
let start = 0;
while (true) {
const i = input.indexOf(', ', start);
if (i === -1) { // No separator at all
return -1;
}
if (i === 0) { // Separator at begin of string
return 0;
}
if (input[i - 1] !== ',') { // Found the separator without a preceding comma
return i;
}
start = i + 2; // Looks further
};
}
但是,此函数无法正确处理
,,,
(一个转义逗号和分隔符)。它将前面的逗号视为转义字符,即使它不是。
我该如何解决这个问题?
要将字符串在非“转义”逗号之前分成两部分,您可以使用
String.match()
模式,例如
const parts = input.match(/^([^,]*(?:,,[^,]*)*),\s*(.*)/)
请参阅 正则表达式演示。
详情:
^
- 字符串的开头([^,]*(?:,,[^,]*)*)
- 第 1 组:零个或多个除逗号之外的字符,然后出现零个或多个 ,,
,后跟零个或多个除逗号之外的字符,\s*
- 逗号和零个或多个空白字符(.*)
- 第 2 组:字符串的其余部分。如果您仅限于
String.split
、和,您的正则表达式将在 ECMAScript 2018+ JavaScript 环境中运行,您可以使用拆分方法
const parts = input.split(/(?<=(?<!,)(?:,,)*), (.*)/)
请参阅 此正则表达式演示。
详情:
(?<=(?<!,)(?:,,)*)
- 积极的回顾,确保有
(?<!,)
- 前面没有逗号的位置(?:,,)*
- 然后出现零次或多次偶数逗号,
- 逗号和空格。(.*)
- 第 1 组:捕获字符串的其余部分。演示:
const inputs = ['a,, b,, c, d, e,, f', 'a,, b,, c,,, d, e,, f'];
for (var input of inputs) {
console.log(`== Testing: ${input}`)
const [_, url, description] = input.match(/^([^,]*(?:,,[^,]*)*),\s*(.*)/)
console.log(`URL: '${url}', Description: '${description}'.`)
console.log(input.split(/(?<=(?<!,)(?:,,)*), (.*)/).filter(Boolean))
}