AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 780893
Accepted
An5Drama
An5Drama
Asked: 2024-07-27 13:29:47 +0800 CST2024-07-27 13:29:47 +0800 CST 2024-07-27 13:29:47 +0800 CST

是否有一个正则表达式工具仅遵循 BRE 并且在未定义时抛出错误?

  • 772

我正在阅读《灵活性软件设计 (SDF)》。练习 2.10 要求实现BRE 和 ERE 的翻译器。本书使用像 ERE 中grep那样测试翻译的字符串(a.c)来捕获类似abc或 的内容adc。

我使用 Arch Linux。


根据POSIX 规范9.3.3 BRE 特殊字符,\+不受 BRE 支持。

但是man grep“基本与扩展正则表达式”允许\+使用默认选项 BRE。

上述差异似乎是由此规范问题(此 QA的参考)暗示的:

BRE 对应于 ed 或historical grep 类型

不过ed好像也支持\+。


(已编辑:此段内容有误,因为启用选项 b 时,该网站根本不符合 BRE。(ab)而不是\(ab\)将匹配“ab”。)https://www.regexplanet.com/advanced/postgresql/index.html可以支持单纯的 BRE,但它有点慢,并且不能轻易地合并到 Scheme 代码中(我正在学习 SICP 和 SDF,所以我没有检查 Scheme 中的 Http 实现。上面的书使用 shell 来运行grep)。我使用表达式a\+c和输入abc在启用选项 b 的情况下进行测试。它显示“regex_matches()”为“(none)”。

那么是否有一个正则表达式工具完全遵循BRE?

grep
  • 1 1 个回答
  • 123 Views

1 个回答

  • Voted
  1. Best Answer
    Ed Morton
    2024-07-27T20:31:06+08:002024-07-27T20:31:06+08:00

    POSIX 定义了一些字符,称为元字符或“特殊字符”,它们在正则表达式中使用时具有非文字含义,例如.匹配任何字符。POSIX 还定义了在这样的元字符前放置反斜杠时会发生什么\,即它变为文字,因此\.匹配文字.字符。

    s例如(或在 BRE 中),不是此类元字符的字符+称为“普通字符”。POSIX 对普通字符的定义如下(重点是我的):

    9.3.2 BRE 普通字符

    普通字符是与自身匹配的 BRE:受支持的字符集中的任何字符,除了 BRE 特殊字符中列出的 BRE 特殊字符。

    对于以非转义字符 ( '\' ) 开头的普通字符的解释是未定义的,但以下情况除外:

    • 字符 ')'、'('、'{' 和 '}'
    • 数字 1 至 9(含)(请参阅BRE 匹配多个字符)
    • 括号表达式内的字符

    即,它没有明确定义当你\在普通字符前面放置一个时会发生什么(除了上面提到的几个),这就是为什么工具可以定义为与该工具\s相同的含义并且仍然符合 POSIX 标准,因为任何工具都可以根据输入做任何它喜欢的事情,以至于 POSIX 没有定义如何处理该输入。[[:space:]]

    关于:

    是否有一个完全遵循 BRE 的正则表达式工具?

    大多数(全部?)grep和sed实现默认都是这样的,但是像我认为您希望的那样,仅实现 POSIX 定义的行为的工具根本就不可能存在,因为 POSIX 故意没有定义所有内容(POSIX 描述了大多数工具在大多数情况下都具有的通用功能,它并没有规定所有工具在所有情况下必须如何表现),因此,无论谁实现任何版本的任何工具,都必须自己决定当该工具遇到某些未由 POSIX 定义的输入时该做什么 - 实现一些他们认为有用的功能,将其视为文字字符,打印警告消息,删除所有文件,损坏硬盘或任何其他他们认为合适的操作。只要它们实现了 POSIX 定义的功能,那么该工具就是符合 POSIX 的,无论它在未定义的情况下做什么。

    假设汽车有这样一条标准:“当驾驶员将方向盘向右转动时,汽车向右转”。汽车制造商应该遵守该要求。该标准可能没有定义当您将方向盘拉向自己时会发生什么,因此如果日产决定,如果您在 2015 年的 Maxima 中这样做,那么汽车就会起飞并开始飞行或压缩成一个小立方体,这仍然符合标准。同样,POSIX 定义了.、s和的\.含义,但 POSIX 没有定义\s含义,因此 GNU 可以定义\s为等同于[[:space:]]或任何他们喜欢的内容,同时仍然符合 POSIX 标准。

    因此,如果您希望正则表达式在所有版本的工具中都具有相同的行为(例如grep按照 POSIX 定义的方式),那么就不要编写依赖于 POSIX 未定义行为的正则表达式。这包括不在\+BRE 中编写,不在 BRE 或 ERE 中编写\s,这样,grep在处理该正则表达式时,您使用的任何内容都将符合适用的 POSIX 标准。

    POSIX 正则表达式、BRE 和 ERE 是在POSIX 标准中定义的,不在任何给定工具的手册页中,而且肯定也不在 regex101.com 上,据我所知,该网站没有处理 POSIX BRE 或 ERE 的选项。

    关于评论中设置的建议POSIXLY_CORRECT:POSIXLY_CORRECT仅适用于 GNU 工具,因此它对 BSD 等工具没有帮助,并且即使在 GNU 中,它的作用也因工具而异,例如在设置了 POSIXLY_CORRECT 的 GNU awk 中,它会报告为\s未定义的行为并将其视为正则表达式s中的文字,而在 GNU grep 中,无论是否设置了 POSIXLY_CORRECT,它都会以相同的方式处理\s(和\+)。例如:

    $ echo 'a b' | gawk '/a\sb/'
    a b
    
    $ echo 'a b' | grep 'a\sb'
    a b
    
    $ echo 'a b' | POSIXLY_CORRECT=1 gawk '/a\sb/'
    gawk: cmd. line:1: warning: regexp escape sequence `\s' is not a known regexp operator
    
    $ echo 'a b' | POSIXLY_CORRECT=1 grep 'a\sb'
    a b
    

    $ echo 'asb' | gawk '/a\sb/'
    $
    
    $ echo 'asb' | grep 'a\sb'
    $
    
    $ echo 'asb' | POSIXLY_CORRECT=1 gawk '/a\sb/'
    gawk: cmd. line:1: warning: regexp escape sequence `\s' is not a known regexp operator
    asb
    
    $ echo 'asb' | POSIXLY_CORRECT=1 grep 'a\sb'
    $
    
    • 6

相关问题

  • 来自 `service | 的意外结果 grep`

  • 读取带有单词的文本文件及其出现次数和排序的打印输出

  • 命令 ls | grep 只显示目录(当它也应该显示文件时)

  • grep 什么时候计数,什么时候不计数

  • grep --line-buffered 直到 X 行?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve