我可以对 POSIX 括号表达式进行否定吗?
Can I do a negation of a POSIX bracket expression?
我知道我可以搜索匹配 space 和 POSIX 括号表达式 [[:space:]]
的内容。我可以使用 POSIX 括号表达式搜索与 space 不匹配的内容吗?特别是,它应该匹配的字符包括字母和括号 ((
).
[[:graph:]]
看起来有点模糊:
[[:graph:]]
- Non-blank character (excludes spaces, control characters, and similar)
嗯,如果
'foo bar'[ /[[:space:]]/ ] # => " "
匹配 space,为什么这行不通?
'foo bar'[ /[^[[:space:]]]/ ] # => "f"
例如,像这样:
'foo bar'.scan(/[^[[:space:]]]+/) # => ["foo", "bar"]
重要的是要记住 [[:space:]]
是一个字符 class,就像 \s
或 \d
或它们的否定版本一样。由于 \S
类似于 [^\s]
我们可以使用 [^[[:space:]]]
.
I think that should be [^[:space:]] since [:space:] is what expands inside the set notation [...].
我使用 [[...]]
形式,因为那是 Regexp 中记录的内容。
为清楚起见,这里有一些示例没有使用文档中所示的双括号,而是遵循以下注释:
'foo bar'[ /[[:space:]]/ ]# => " "
'foo bar'[ /[^[:space:]]/ ]# => "f"
'foo bar'[ /[^[[:space:]]]/ ]# => "f"
请注意,这不起作用:
'foo bar'[ /[:space:]/ ]# => "a"
/[:space:]/
被正则表达式引擎解释为:
/[:space]/
这是一个常规字符集,不是元形式。这就是它在 "foo bar".
中匹配 'a'
的原因
你在这里混淆了两件事:bracket expression and a POSIX character class。外层的 [...]
是括号表达式,可以用 [
后面的 ^
取反。 POSIX 字符 class 是一个 [:
+name
+:]
结构,只能在方括号表达式中使用。
因此,在您的情况下,[[:space:]]
模式是一个括号表达式,仅包含 1 个 POSIX 字符 class 匹配空格:
[
- 左括号表达式
[:space:]
- POSIX 字符 class 用于空格
]
- 括号表达式的右括号。
要否定它,只需像通常的 NFA character classes 一样添加 ^
:[^[:space:]]
.
请注意,我故意区分术语 "bracket expression"、"POSIX character class" 和 "character class",因为 POSIX 和常见的 NFA 正则表达式世界遵循不同的术语。
看来这个变体也能解决问题:
/[[:^alpha:]]+/.match("ab12")
结果:
#<MatchData "12">
我知道我可以搜索匹配 space 和 POSIX 括号表达式 [[:space:]]
的内容。我可以使用 POSIX 括号表达式搜索与 space 不匹配的内容吗?特别是,它应该匹配的字符包括字母和括号 ((
).
[[:graph:]]
看起来有点模糊:
[[:graph:]]
- Non-blank character (excludes spaces, control characters, and similar)
嗯,如果
'foo bar'[ /[[:space:]]/ ] # => " "
匹配 space,为什么这行不通?
'foo bar'[ /[^[[:space:]]]/ ] # => "f"
例如,像这样:
'foo bar'.scan(/[^[[:space:]]]+/) # => ["foo", "bar"]
重要的是要记住 [[:space:]]
是一个字符 class,就像 \s
或 \d
或它们的否定版本一样。由于 \S
类似于 [^\s]
我们可以使用 [^[[:space:]]]
.
I think that should be [^[:space:]] since [:space:] is what expands inside the set notation [...].
我使用 [[...]]
形式,因为那是 Regexp 中记录的内容。
为清楚起见,这里有一些示例没有使用文档中所示的双括号,而是遵循以下注释:
'foo bar'[ /[[:space:]]/ ]# => " "
'foo bar'[ /[^[:space:]]/ ]# => "f"
'foo bar'[ /[^[[:space:]]]/ ]# => "f"
请注意,这不起作用:
'foo bar'[ /[:space:]/ ]# => "a"
/[:space:]/
被正则表达式引擎解释为:
/[:space]/
这是一个常规字符集,不是元形式。这就是它在 "foo bar".
中匹配'a'
的原因
你在这里混淆了两件事:bracket expression and a POSIX character class。外层的 [...]
是括号表达式,可以用 [
后面的 ^
取反。 POSIX 字符 class 是一个 [:
+name
+:]
结构,只能在方括号表达式中使用。
因此,在您的情况下,[[:space:]]
模式是一个括号表达式,仅包含 1 个 POSIX 字符 class 匹配空格:
[
- 左括号表达式[:space:]
- POSIX 字符 class 用于空格
]
- 括号表达式的右括号。
要否定它,只需像通常的 NFA character classes 一样添加 ^
:[^[:space:]]
.
请注意,我故意区分术语 "bracket expression"、"POSIX character class" 和 "character class",因为 POSIX 和常见的 NFA 正则表达式世界遵循不同的术语。
看来这个变体也能解决问题:
/[[:^alpha:]]+/.match("ab12")
结果:
#<MatchData "12">