如何从 javascript 中的某个位置匹配正则表达式模式?
How to match a regex pattern from a certain position in javascript?
我正在尝试在 javascript 中使用正则表达式匹配降价 header。降价 header 是一个字符串,从一个或多个 #
开始,后跟一个或多个空格和一些文本,如下所示:
## This is the title
棘手的是,我得到了一个 multi-line 字符串和一个 0 索引的起始位置,我需要检查从给定位置开始的字符串是否 starts 降价 header。换句话说,我需要编写以下函数:
/**
* The function should return true in the following situations:
* - text: "abc\n# My Title", startPos = 4
* - text: "abc\n# My Title\nxyz", startPos = 4
*
* The function should return false in the following situation:
* - text "abc\n#My Title", startPos = 0
*/
function isMarkdownHeader(text, startPos) {
...
}
这是我试过的方法:
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^[^]{${startPos}}(^#+)(\s+)(.*$)`, 'm');
return pattern.exec(text) != null;
}
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 4)); // true
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 0)); // true, which is incorrect.
该函数应该在第二次调用时 return false
。但它没有。为什么?我怎样才能让它发挥作用?
您不需要正则表达式从特定位置开始。您可以只传递从 startPos
:
开始的子字符串
return pattern.exec(text.substring(startPos)) != null;
使用正则表达式的解决方案
你可以使用
^.{4}(#+\s+.*)
函数看起来
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^.{${startPos}}#+\s+.*`, "s");
return pattern.exec(text) != null;
}
isMarkdownHeader("abc\n## My Title\nxyz", 4) // true
isMarkdownHeader("abc\n## My Title\nxyz", 0) // false
注意:这里我使用了 s
标志。另外,请参阅 demo.
使用 Slice 的解决方案
您可以在检查有效性之前对输入字符串进行切片。
function isMarkdownHeader(text, startPos) {
const pattern = /^#+\s+.*/;
return !!pattern.exec(text.slice(startPos));
}
isMarkdownHeader("abc\n## My Title\nxyz", 4) // true
isMarkdownHeader("abc\n## My Title\nxyz", 0) // false
编辑
isMarkdownHeader("abcd## My Title\nxyz", 4)
should return false
. With your code, the return value is true
发生这种情况是因为称为换行符的东西和 \n
字符不是一回事。字符串中的\n
是换行符的常规字符,打印字符串后就变成了换行符。所以如果你想匹配他们两个然后使用
^.{4}(?:^|\n|\n)(#+\s+.*)
这里我在旧的基础上添加了(?:^|\n|\n)
模式
(?:
Non-capturing组
^|\n|\n
匹配 字符串开头 或 换行符 或 \n
字符
)
关闭non-capturing群
它匹配
abcd\n## My Title\nxyz
abcd⏎## My Title\nxyz
其中 ⏎
是换行符
它不匹配
P.S。要匹配 abc\n## My Title\nxyz
,您必须使用 3
作为 startPos
,不包括 \n
字符。
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^.{${startPos}}(?:^|\n|\\n)(#+\s+.*)`, "s");
return pattern.exec(text) != null;
}
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 3)) // true
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 0)) // false
console.log(isMarkdownHeader("abcd## My Title\nxyz", 4)) // false
根据 Regex101,{0}
量词导致前面的标记被忽略。没有引文支持这一点,但我会相信他们的话。
既然如此,您可以检查您的匹配项是否从索引 0 开始(这表明字符串以正确数量的忽略字符开始)。
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^[^]{${startPos}}(^#+)(\s+)(.*$)`, 'm');
const match = pattern.exec(text);
return match?.index === 0;
}
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 4)); // true
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 0)); // now false
我正在尝试在 javascript 中使用正则表达式匹配降价 header。降价 header 是一个字符串,从一个或多个 #
开始,后跟一个或多个空格和一些文本,如下所示:
## This is the title
棘手的是,我得到了一个 multi-line 字符串和一个 0 索引的起始位置,我需要检查从给定位置开始的字符串是否 starts 降价 header。换句话说,我需要编写以下函数:
/**
* The function should return true in the following situations:
* - text: "abc\n# My Title", startPos = 4
* - text: "abc\n# My Title\nxyz", startPos = 4
*
* The function should return false in the following situation:
* - text "abc\n#My Title", startPos = 0
*/
function isMarkdownHeader(text, startPos) {
...
}
这是我试过的方法:
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^[^]{${startPos}}(^#+)(\s+)(.*$)`, 'm');
return pattern.exec(text) != null;
}
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 4)); // true
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 0)); // true, which is incorrect.
该函数应该在第二次调用时 return false
。但它没有。为什么?我怎样才能让它发挥作用?
您不需要正则表达式从特定位置开始。您可以只传递从 startPos
:
return pattern.exec(text.substring(startPos)) != null;
使用正则表达式的解决方案
你可以使用
^.{4}(#+\s+.*)
函数看起来
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^.{${startPos}}#+\s+.*`, "s");
return pattern.exec(text) != null;
}
isMarkdownHeader("abc\n## My Title\nxyz", 4) // true
isMarkdownHeader("abc\n## My Title\nxyz", 0) // false
注意:这里我使用了 s
标志。另外,请参阅 demo.
使用 Slice 的解决方案
您可以在检查有效性之前对输入字符串进行切片。
function isMarkdownHeader(text, startPos) {
const pattern = /^#+\s+.*/;
return !!pattern.exec(text.slice(startPos));
}
isMarkdownHeader("abc\n## My Title\nxyz", 4) // true
isMarkdownHeader("abc\n## My Title\nxyz", 0) // false
编辑
isMarkdownHeader("abcd## My Title\nxyz", 4)
should returnfalse
. With your code, the return value istrue
发生这种情况是因为称为换行符的东西和 \n
字符不是一回事。字符串中的\n
是换行符的常规字符,打印字符串后就变成了换行符。所以如果你想匹配他们两个然后使用
^.{4}(?:^|\n|\n)(#+\s+.*)
这里我在旧的基础上添加了(?:^|\n|\n)
模式
(?:
Non-capturing组^|\n|\n
匹配 字符串开头 或 换行符 或\n
字符
)
关闭non-capturing群
它匹配
abcd\n## My Title\nxyz
abcd⏎## My Title\nxyz
其中⏎
是换行符
它不匹配
P.S。要匹配 abc\n## My Title\nxyz
,您必须使用 3
作为 startPos
,不包括 \n
字符。
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^.{${startPos}}(?:^|\n|\\n)(#+\s+.*)`, "s");
return pattern.exec(text) != null;
}
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 3)) // true
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 0)) // false
console.log(isMarkdownHeader("abcd## My Title\nxyz", 4)) // false
根据 Regex101,{0}
量词导致前面的标记被忽略。没有引文支持这一点,但我会相信他们的话。
既然如此,您可以检查您的匹配项是否从索引 0 开始(这表明字符串以正确数量的忽略字符开始)。
function isMarkdownHeader(text, startPos) {
const pattern = new RegExp(`^[^]{${startPos}}(^#+)(\s+)(.*$)`, 'm');
const match = pattern.exec(text);
return match?.index === 0;
}
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 4)); // true
console.log(isMarkdownHeader("abc\n## My Title\nxyz", 0)); // now false