有人可以帮助我使用此 javascript 正则表达式将一串列表项转换为仅包含项目文本的数组(没有列表项#或换行符)

Can someone help me with this javascript regex to turn a string of list items into an array with the item texts only (no list item # or new line)

我有两种从 API 返回的字符串。它们看起来如下:

let string1 = "\n1. foo\n2. bar\n3. foobar"
let string2 = "\n\n1. foo.\n\n2. bar.\n\n3. foobar."

明确地说,string 1 总是有 3 个项目返回,string 2 有未知数量的项目返回。但是非常相似的模式。

我想做的是只从每个项目中提取文本到一个数组中。

所以从 string1 我想要 ["foo", "bar", "foobar"] 来自 string2 我想要 ["foo.", "bar.", "foobar."]

我对正则表达式很糟糕,但不知何故,我无意中发现了一个表达式,它可以为两种字符串类型实现这一点,但是,它使用正则表达式的后视,我试图避免这种情况,因为所有浏览器都不支持它:

let regex = /(?<=\. )(.*[a-zA-Z])/g;
let resultArray = str.match(regex);

有人能帮我将这个正则表达式重构为不使用 lookbehind 的东西吗?

编辑:请参阅@Oleg-Barabanov 的解决方案,从技术上讲它要快一些。

string.replace(/\n[0-9.]*/g, "").split(" ").slice(1)
  • \n换行
  • 0-9 用于数字(也可以使用 \d
  • .为数字后的点
  • g 替换所有
  • .split(" ") 在有 space (\s)
  • 的地方砍掉它

演示:

let string1 = "\n1. foo\n2. bar\n3. foobar"
let string2 = "\n\n1. foo.\n\n2. bar.\n\n3. foobar."

const parse = (str) => str.replace(/\n[0-9.]*/g, "").split(" ").slice(1)


console.log(parse(string1))
console.log(parse(string2))

如果我对你的理解是正确的,那么也许这个解决方案可以帮助你:

const string1 = "\n1. foo\n2. bar\n3. foobar";
const string2 = "\n\n1. foo.\n\n2. bar.\n\n3. foobar.";

const parse = (str) => {
  return str.split(/\n[0-9.\s]*/g).filter((item) => item !== "");
}

console.log('Example 1:', parse(string1));
console.log('Example 2:', parse(string2));

OP 的代码使用 String.match,实际上比建议的解决方案更好。它只需要一个小的调整就可以工作,这就是问题所在:

string1.match(/([A-z].+)/g)

// TEST

[

 "\n1. foo\n2. bar\n3. foobar", 
 "\n\n1. foo.\n\n2. bar.\n\n3. foobar."

].forEach(p => {

  console.log( p.match(/([A-z].+)/g) )

});

关于您尝试过的模式 (?<=\. )(.*[a-zA-Z]) 的一些注释:

  • 第一部分断言左侧有一个点和 space,但不考虑任何换行符,因此它也可能匹配其他位置

  • 匹配列表项不考虑数字

  • 你的模式的第二部分匹配到字符 A-Za-z 的最后一次出现,它不匹配 string2

    示例中的结束点

所有示例字符串都以换行符、数字、点和 1 个或多个 space 开头。

您可以在不使用回顾的情况下获得匹配,并通过以列表项格式开始匹配来使模式更加具体。

然后在捕获组中捕获该行之后的其余部分。

\n\d+\.[^\S\r\n]+(.+)

说明

  • \n 匹配一个换行符
  • \d+\. 匹配 1+ 个数字和一个点
  • [^\S\r\n]+ 匹配 1 个或多个 space 没有换行符
  • (.+) 捕获组 1,匹配 1 个或多个字符

看到一个regex demo.

const regex = /\n\d+\.[^\S\r\n]+(.+)/g;
[
  "\n1. foo\n2. bar\n3. foobar",
  "\n\n1. foo.\n\n2. bar.\n\n3. foobar."
].forEach(s => {
  console.log(Array.from(s.matchAll(regex), m => m[1]))
});


如果字符串也应该在没有前导换行符的情况下匹配,您可以使用锚点 ^ 断言字符串的开头并使用多行标志 /m

const regex = /^\d+\.[^\S\r\n]+(.+)/gm;
[
  "1. foo\n2. bar\n3. foobar",
  "1. foo.\n\n2. bar.\n\n3. foobar."
].forEach(s => {
  console.log(Array.from(s.matchAll(regex), m => m[1]))
});