$ grep '[^az]\{22\}' /usr/share/dict/words 无输出

$ grep '[^az]\{22\}' /usr/share/dict/words 无输出

执行后

grep '[a-z]\{22\}' /usr/share/dict/words

输出是

counterrevolutionaries
electroencephalographs

但在执行时

grep '[^a-z]\{22\}' /usr/share/dict/words

没有输出。

我预计它会产生与

grep -v '[a-z]\{22\}' /usr/share/dict/words

我的问题是出了什么问题以及为什么?

答案1

[specification]匹配排序元素(可以是区域设置排序算法中定义的字符或字符序列(例如,在 GNU 系统上的匈牙利语言环境中,是在和dzs之间排序的排序元素))de指定的放。

该规范可以包括

  • a-z(或) 这样的范围用于整理在和[.dzs.]-z之间整理的元素(请注意,它通常包括 abcdefghijklmnoprstuvwxyz,但在大多数语言环境中,它包括更多内容)。此外,由于 POSIX 未指定除 POSIX 语言环境之外的其他语言环境,因此这些范围基于排序规则顺序的程度在不同实现之间存在显着差异。az
  • 单个字符或整理元素 ( x, [.dsz.])
  • POSIX 字符类[:alpha:][:digit:]
  • 等效类,例如[=e=]具有相同主要整理权重的所有整理元素e(可能包括诸如 é

因此,例如,[acd[=e=]h-k[:digit:][.dzs.]]如果整理元素上的匹配项是acddzs等于e或 在 和 之间进行整理hk或 则分类为数字

如果规范以 开头^,那么它仍然匹配一个整理元素,但对集合进行补充。这是除指定元素之外的任何整理元素。

因此,[^a-z]匹配任何不在a和之间进行整理的整理元素z。例如,它可能会匹配 on1,可能匹配XDSZ取决于语言环境和grep实现,但不会匹配 on ax也不会匹配z,也可能不会匹配 on é

所以grep '[^a-z]\{22\}'匹配的行包含在 之前或之后22进行整理的整理元素序列。az

Whilegrep -v '[a-z]\{22\}'匹配不包含在a和之间进行整理的 22 个整理元素序列的行z

匹配相同的元素-v几乎不可能实现,您需要匹配[a-z]两个元素之间包含不超过 21 个排序元素的行[^a-z]。但如果语言环境支持多字符整理元素,那实际上是不可能的。例如,在那些匈牙利语言环境中,[a-z]匹配 ondsz但也匹配d, sz因此您会发现在那里,[a-z]{0,21}将匹配 ondszxxxyyyxxxyyyxxxyyyx但也匹配[a-z]{22}

对于没有多字符整理元素的区域设置,您可以执行以下操作:

grep  '^[^a-z]*\([a-z]\{1,21\}[^a-z]\{1,\}\)*[a-z]\{0,21\}$'

现在,还有一些grep实现支持更高级的正则语法,其中的选项具有一些否定操作员。

例如,GNU 或 ast-open 实现grep支持类似 perl(在 GNU grep 中使用 libpcre,ast-open 自己的 ast-open grep 实现)正则表达式,-P其选项具有(?!pattern) 负前瞻运算符

(?!pattern)如果模式从那里开始不匹配,则在主题字符串的任何点上以零宽度进行匹配。所以人们可以使用:

 grep -P '^(?!.*[a-z]{22})'

匹配行的开头,前提是后面没有任何数量的字符和 22[a-z]秒。但请注意,在 PCRE 中(不在 ast-open 中),[a-z]仅匹配 abcdefghijklmnopqrstuvwxyz,无论区域设置如何。

ast-open 还可以选择-X他们所说的选项增强的正则表达式。这些增强的正则表达式有一个!否定事物的运算符。x!将匹配除x(包括空字符串)之外的任何内容。

因此,使用 ast-open grep,您还可以执行以下操作:

grep -X '^(.*[a-z]{22}.*)!$'

答案2

  • grep '[^a-z]\{22\}' /usr/share/dict/words

    查找文件中/usr/share/dict/words包含非小写字母的 22 个字符的字符串的行。该文件很可能不包含任何此类行。 (为什么该文件包含 22 个非字母的字符串?)

  • grep -v '[a-z]\{22\}' /usr/share/dict/words

    查找不包含 22 个字母的字符串的行。可能会有很多这样的线路。 (因为大多数单词都少于 22 个字母。)

相关内容