【问题标题】:Error bash grep: "grep: warning: ? at start of expression" while matching digits between 2 characters [duplicate]错误 bash grep: \"grep: warning: ? at start of expression\" while matching digits between 2 characters
【发布时间】:2022-12-01 01:52:40
【问题描述】:

我正在尝试获取“:”和“M”或“。”之间的所有数字。使用echo ":11379.32 M" | grep -Eo "(?<=\:)(.*?)\d+(?:\d([^\.]|[M]))"但我一直收到错误消息。

嗨,我是这个论坛的新手,如果我在提问时犯了一些错误,请提前致歉。

我正在尝试获取“:”和“M”或“。”之间的所有数字, 运行类似: echo ":11379.32 M" | grep -Eo "(?<=\:)(.*?)\d+(?:\d([^\.]|[M]))"。 我不断收到错误“grep: warning: ? at start of expression”,而如果我通过 regexr.com 运行它,我不会收到任何错误。

据我所知,运行“grep -Eo”应该将正则表达式读取为扩展正则表达式,我不应该遇到转义字符的问题,但我尝试删除“?”字符并通过删除正后视“?<=”和非捕获组“?:”来简化正则表达式,获得如下内容: echo ":11379.32 M" | grep -Eo "^.*?\d+[^\.]", 它仍然适用于 regexr.com,但我在 bash 上得到空输出 (它也有“:”,但我可以用sed命令删除它,所以我不关心它)。 Regex action on regexr.com。

你知道我做错了什么吗?

【问题讨论】:

  • 您缺少 -P 标志,如果可用,请将 -E 更改为 -P。 -E表示ERE,你有的是PCRE
  • ...也就是说,(?&lt;=...) 是 PCRE 扩展名。标准 POSIX ERE 语法中没有先行或后行支持
  • ...请注意,PCRE 语法不仅是 GNU 扩展,还是一个可选的GNU 扩展;即使您知道使用 GNU grep,它也需要使用可选扩展名进行编译,告诉它链接到 libpcre 作为 -P 可用的依赖项。
  • 哦,天哪,它有效,谢谢。
  • (顺便说一下,第一个问题很好。我们有时会因为将我们的问答知识库称为“论坛”而变得烦躁,但您写了一个准确总结您的问题并包含足够细节以重现问题的标题)。

标签: regex bash grep


【解决方案1】:

如果您只针对使用针对 libpcre 编译的 GNU grep 的操作系统,请将 -E 更改为 -P 以使用与 perl 兼容的正则表达式语法;没有 PCRE 扩展,你就没有先行、d 或非贪婪匹配。


如果您想支持范围更广的操作系统,另一种方法是使用标准 bash 内置正则表达式(使用 ERE 语法)来实现这一点,完全避免对 grep 的任何需求:

re=':([[:digit:]]+)([.]|[[:space:]]*M)'
string='1:11379.32 M'

if [[ $string =~ $re ]]; then
  echo "Matched ${BASH_REMATCH[1]}"  # prints "Matched 11379"
else
  echo "No match"
fi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2018-01-25
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2021-04-06
    相关资源
    最近更新 更多