regex 当文本以特定字符串开头时匹配字符串的正则表达式

3ks5zfa0  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(116)

我正在使用ObsidianObsidian_to_Anki-插件。我需要正则表达式匹配所有的第一级标题的一个页面与捕获组,但只有当页面开始与#match。该插件使用多行标志编译正则表达式。这些页面具有这样的结构:

#match

# Heading 1
Text of Heading 1
# Heading 2
Text of Heading 2
# Heading 3
Text of Heading 3

这不应该匹配:

# Heading 1
Text of Heading 1
# Heading 2
Text of Heading 2
# Heading 3
Text of Heading 3

我写了一个Regex:#match\s\s(# .*)。但是这样只有Heading 1与捕获组1匹配,因为在Heading 2之前没有#match
有办法解决吗?
提前感谢!

cs7cruho

cs7cruho1#

更新

(?<=                        # Match something preceded by
  (?<![\s\S])               #          at the start of the file
  #match\n                  # '#match'
  [\s\S]*                   # and anything in between:
)                           # 
^(# .+)\n                   # A heading followed by
([\s\S]+?)                  # its corresponding content, which might be as long as possible,
(?=\n# |<!--ID|(?![\s\S]))  # until another heading, '<!--ID' or the end of file.

试试on regex101.com
由于ECMAScript不支持\A\Z(尽管有a proposal可以添加它们),我们必须使用负查找来做:(?![\s\S]) / (?<![\s\S])[\s\S]匹配any single character,所以(?![\s\S])只能在找不到后续字符的位置匹配:字符串的结尾。同样的解释也适用于(?<![\s\S])

原始答案

(?:\A#match|\G(?!\A))  # Match '#match' at the start of the file, or the end of the last match
\s*                    # followed by 0 or more whitespaces;
\K                     # we forfeit everything we just matched
^(# .+)\n              # then match and capture a heading, before continuing to the next line
([\s\S]+?)             # and capture the section's content,
(?=\n# |\Z)            # which must precedes either another heading or the end of file.

试试on regex101.com
这利用了以下元序列:

  • \A:整个字符串的最开始
  • \G:最后一场比赛的结束或\A
  • \G(?!\A):仅最后一场比赛的结束
  • \K:放弃与其左边表达式匹配的所有内容
  • \Z:字符串的结尾或最后一行结束符之前的位置 iff 它也是整个字符串的最后一个字符。

相关问题