【问题标题】:regex doesn't work with optional ()? sentense正则表达式不适用于可选()?句子
【发布时间】:2021-11-05 08:28:17
【问题描述】:

我尝试使用 bash 从文件夹中获取所有文件,如 scheme_12.sql 和 scheme_23_analytics.sql,正则表达式在终端中以一种奇怪的方式工作,不返回任何内容。还检查了 python re 和一些交互式正则表达式站点。它有效。

我的命令ls | find . -type f -regex "\.\/scheme_[0-9]+_([a-zA-Z]+)?.sql"

但是没有可选语句的命令有效ls | find . -type f -regex "\.\/scheme_[0-9]+.sql"

我不知道为什么。你能帮我找出错误吗?

【问题讨论】:

  • 你从find -regextype help得到什么?
  • 您希望管道lsfind 应该完成什么? ls 是无操作的,因为find 将简单地忽略其标准输入。 You should generally not use ls in scripts 反正。

标签: regex linux bash find


【解决方案1】:

有几个问题:

  • 您正在使用 POSIX BRE 模式,其中组语法是 \(...\),而不是 (...)+ 量词通常写为 \{1,\} 或从 a+ 重写为 aa*
  • ([a-zA-Z]+)? 部分等于[a-zA-Z]*,前面的下划线仍然是必填。您需要将_ 和字母的整个序列设置为可选
  • sql 之前的文字点必须转义,否则它将匹配任何字符
  • / 字符不需要在 find 正则表达式中进行转义,因为它不使用正则表达式分隔符。

这是一个 POSIX ERE 解决方案:

find . -type f -regextype posix-extended -regex '\./scheme_[0-9]+(_[[:alpha:]]+)?\.sql'

所以,(_[[:alpha:]]+)? 在这里定义了_ 和一个或多个字母的可选序列。

【讨论】:

    【解决方案2】:

    默认的正则表达式类型不支持该构造。使用-regextype 指定一个不同的,posix-extended 如果可用,例如应该支持它。

    另外,为什么要将ls 的输出通过管道传输到findfind 不需要来自标准输入的任何内容。

    $ touch scheme_12.sql  scheme_23_analytics.sql
    $ find . -type f -regextype posix-extended -regex "\.\/scheme_[0-9]+_([a-zA-Z]+)?.sql"
    ./scheme_23_analytics.sql
    

    要取回这两个文件,您需要在可选字符类中移动下划线。

    【讨论】:

    • 感谢您的回答。这是我的拼写错误,仅在此示例中带有可选字符类之外的下划线。删除了 ls 并将正则表达式添加到命令中,但它也不起作用
    • 通过在可选字符类中的下划线前添加“\”找到了解决方案
    • 这没有任何意义。您可以发布对您有用的命令吗?您是否尝试逐字复制我的示例?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2013-09-08
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多