【问题标题】:Problem with the outputs from using double square brackets使用双方括号的输出问题
【发布时间】:2020-10-24 12:29:26
【问题描述】:

有人告诉我[[a-z][0-9]] 等同于[a-z0-9],但我尝试了几个例子:

grepl("[[a-z][0-9]]", "d") 返回FALSE

类似地,grepl("[[:alpha:][0-9]]", "d") 返回 FALSE 而像 grepl("[[:upper:][:lower:]]", "d") 这样的东西可以正常工作。

请问这是否表明双方括号只能用于组合"[:...:]" 形式的事物,而不能用于组合[A-z][0-9] 之类的事物?

如果是这样,为什么 R 会阻止我们这样做?而grepl("[[a-z][0-9]]", "d")grepl("[[a-z]]", "d") 究竟是什么意思?

此外,我知道我们需要使用双方括号,比如"[[:digit:]]",因为"[:digit:]" 宁愿搜索“:”、“d”、“i”、“g”或“ t"(来自this 问题)。但是"[[:digit:]]" 的结构究竟是如何解释的呢? (只是一个猜测:R 是否将其解释为 [:digit:] 与自身的微不足道的联合,因此它只是 R 的“可读”[:digit:]?)

【问题讨论】:

    标签: r regex


    【解决方案1】:

    您应该小心正则表达式中的方括号。 现在,我假设您正在使用与基本 R 正则表达式函数一起使用的默认 TRE 正则表达式库(当没有传递 perl=TRUE 时)。

    在这种情况下,你应该区分

    • [] 标记 POSIX character class 的开始和结束,例如[:alpha:]
    • [] 标记 bracket expression 的开始和结束
    • 未转义 ] 前面没有匹配的未转义打开 [ 被视为文字 ] 字符。

    [[a-z][0-9]] 正则表达式不等于 [a-z0-9]

    • [[a-z][0-9]] matches strings[1], a1] 和意味着:
      • [[a-z] - 匹配 [ 字符或任何小写 ASCII 字母的括号表达式
      • [0-9] - 一个数字
      • ] - ] 字符。

    [a-z0-9] 括号表达式只是 matches 一个小写的 ASCII 字母或数字。

    在正则表达式中没有像双方括号这样的结构。在字符类中,[ 可以在任何地方使用以匹配 [ 字符。 ] 仅在 ] 放置在括号表达式的开头时匹配:

    • [a-z[] 匹配单个字符、小写 ASCII 字母或 [
    • [][a-z] 匹配单个字符、小写 ASCII 字母、[]
    • [[a-z]] 匹配一个小写的 ASCII 字母或 [,然后是一个 ] 字符(因此,总共 2 个字符)

    需要考虑的更多事项

    【讨论】:

    • 感谢您的帮助澄清!我现在了解其中的大部分。请问R如何知道字符类中的[literal char还是POSIX字符类的开始? (正如您所说的“在字符类中,[ 可以在任何地方使用以匹配 [ char”)是因为 R 检测到 : 跟在 [ 之后的 POSIX 字符类?
    • @J-A-S 正则表达式是从左到右解析的,一旦正则表达式引擎进入括号表达式,它就会确切地知道它可以在括号表达式中匹配什么。因此,如果[ 在那里匹配,则检查下一个字符,因为它是:,所以检查下一个字符等,直到:],然后根据有效的 POSIX 字符类名称检查找到的名称,然后继续...所以,请注意:[[:] 将失败并出现Unknown character class name 错误,请确保括号表达式中没有“悬空”[:[:[] 将起作用。在更智能的 PCRE 正则表达式中,您可以使用 [[:]
    • 谢谢 :) 这很有意义。顺便说一句,感谢您在上一节中提供的 2 个额外信息
    • 您好,很抱歉再次打扰您,请问为什么'[]-/]''[]-//]' 是无效字符范围而'[]/-]''[]//-]' 不是?
    • @J-A-S 一般见this threadthis answer,请注意- 在Unicode 表中创建了两个字符之间的范围,这两个字符必须符合规则:第一个必须在表中具有较低的 ID,而第二个(范围上限)必须具有较高的 ID。如果 ID 的顺序相反,则会出现无效范围错误。如果您需要使用文字-,请将其放在括号表达式的末尾。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    相关资源
    最近更新 更多