regex - 如何以非贪婪的方式使用正则表达式提取跨越多行的字符串?
问题描述
我正在探索使用 json 数据结构标记 MarkDown 文件的可能性。
json 数据可以通过将它们放在“评论”中来隐藏打印输出,请参阅StackOverflow - Markdown 中的评论
[json]:# (
[
"json goes here"
]
)
为了提取我一直在使用正则表达式的 json 标签并想出
\[json]:#.\(([^*]*)\)
但是,这仅适用于我在 md 文件中只有一个 [json]-tag 的情况。
(见一个标签)
使用多个标签时,正则表达式会变得贪婪并包含第一个标签和最后一个标签之间的所有内容:/
(请参阅多个标签)
这是重现问题的示例代码
$md = @'
[json]:# (
[
{"jira": "proj-4753"},
{"creation": "2021-09-25"}
]
)
# Title
## 1. Conclusion
Jada, jada
## 2. Recomendation
blah, blah
[json]:# (
[
{"sensitivity": "internal"}
]
)
More data
[json]:# (
[
{"uid": "abc002334"}
]
)
[json]:# (
[
{"mode": "hallow"}
]
)
and this
'@
($md | Select-String '\[json]:#.\(([^*]*)\)').Matches.Value
没有提供输出,因为它将是除了最后一行之外的完整 md
...
使用多个标签并指定标签 2 时的正确输出示例应该是
($md | Select-String '<a working regexp>' -AllMatches).Matches[1].Value
[json]:# (
[
{"sensitivity": "internal"}
]
)
($md | Select-String '<a working regexp>' -AllMatches).Matches.Value
[json]:# (
[
{"jira": "proj-4753"},
{"creation": "2021-09-25"}
]
)
[json]:# (
[
{"sensitivity": "internal"}
]
)
[json]:# (
[
{"uid": "abc002334"}
]
)
[json]:# (
[
{"mode": "hallow"}
]
)
我当然可以选择每个 md 只使用一个 [json] 标签。
还有一个可选的解决方案是将标签只保留在一行上,但这会妨碍可读性。
这不会产生非常健壮的代码,因为有两个非常可能的场景(多标签和多行标签)会破坏代码。
解决方案
由于有效的 json 注释后面总是跟一个换行符\n
,然后是一个右括号)
,所以使用它作为你的模式结束锚:
if($md -match '(?s)\[json]:#.\(\s*(.*?)\s*\n\)'){
$Matches[1]
}
(?s)
是“单行模式”的正则表达式引擎选项,它.
匹配换行符,允许我们使用.*?
.
$Matches
是一个自动变量-match
,当操作在标量模式下成功时,将填充所有捕获组值。
结果:
[
{"jira": "proj-4753"},
{"creation": "2021-09-25"}
]
推荐阅读
- python - 将完美代码复制到另一个代码时出现全局名称未定义问题
- sql - Database.ExecuteSqlCommand() 内联参数错误
- matlab - 在 MatLab 函数中使用工作区中更改名称的变量
- java - Zip文件在服务器端很好,但在服务到客户端后损坏
- python-3.x - 接受类型并返回给定类型值的函数的 Python 类型注释
- php - 如何更改用于谷歌折线图的数据结构
- android - 如何将最大值/最小值添加到饼图
- javascript - 为什么 readFile 拆分;和 readFileSync 不是吗?
- python - Pandas 在两列上计算单个均值、标准差和计数
- android - 如何将 API 重放的 JSON 中的值放到另一个 API 发布方法的主体中?