regex - 使用正则表达式匹配第 N 次出现
问题描述
我正在尝试解析一个字符串并使用正则表达式匹配第 n 次出现。我目前正在处理的示例是提取字符串中的第三个美元值。现在这可能是字符串中的第二个或第四个或第 n 个值,但下面的示例特别是第三个美元值。
字符串:$4,233.65 $5,073.64 $9,307.29 $9,273.41 $0.00 $0.00 $33.88
我要匹配的值:$9,307.29
到目前为止我想出的正则表达式:(?<=\$)\S+
到目前为止的代码匹配美元符号后的每个值,所以问题是,我如何获取第三个(或第 n 个)值?
解决方案
从使用带有 libpcre 的 GNU grep 的命令行:
$ echo '$4,233.65 $5,073.64 $9,307.29 $9,273.41 $0.00 $0.00 $33.88' \
|grep -Po '^(?:[^$]*\$){3}\K\S+'
9,307.29
(Regex101的解释)这使用可变宽度的正向后视,并非所有语言都支持,简化为\K
(foo\Kbar
与 相同(?<=foo)bar
,匹配来自“foobar”的“bar”)。这会跳过两美元的金额(它使用它{3}
是因为我们还包括了前导$
,因为这不是所需匹配的一部分),然后匹配下一个非空白字符。
您可以在 Javascript 中使用相同的逻辑:
let test = "$4,233.65 $5,073.64 $9,307.29 $9,273.41 $0.00 $0.00 $33.88";
test.match(/^(?:[^$]*\$){3}(\S+)/)[1]; // "9,307.29"
这基本上是相同的正则表达式(在 Regex101 解释),但不是\K
在比赛前使用,而是在第一个捕获组中得到了所需的部分,它match()
保存在数组索引 1 中(索引 0 是整个匹配,包括前导部分,因为我们没有使用…\K
或(?<=…)
使其为零宽度)。
但是,如果您使用的是 Javascript 之类的编程语言,则最好以编程方式进行:
let test = "$4,233.65 $5,073.64 $9,307.29 $9,273.41 $0.00 $0.00 $33.88";
test.match(/\$\S+/g)[2].substring(1); // "9,307.29"
(Regex101 的解释)这是更多的非正则表达式代码,但更干净。在这里,我只是在寻找美元值,获取第三个值(回想一下,数组是零索引的),并使用substring()
剥离前导$
(字符串也是零索引)。
注意,Javascript 不支持像…\K
或(?<=…)
推荐阅读
- outlook - Outlook REST API EventMessage 需要所有和共享约束权限
- javascript - 用 Babel 检查哪个 JS 模块需要转译
- c++ - c++中的编译器优化
- reactjs - 在第一次加载组件时未调度 useEffect 中的调度
- c# - 略有不同的子类
- python - 在 python 3 中将出生日期 pandas 数据框拆分为 3 个不同的列
- javascript - fs.watch() 在 Node v13 中是否损坏或者我做错了什么?
- javascript - Discord JS 错误:UnhandledPromiseRejectionWarning:DiscordAPIError:无法向该用户发送消息
- python - 合并 CSV 文件与其中任何一个的架构有关
- typescript - 约束 NonNullable 的类型参数