如何在 Swift NSRegularExpression 中捕获单词边界?
How to capture a word boundary in Swift NSRegularExpression?
我想捕获以某个前缀开头的字符串中的所有 单词 。例如所有以 t
开头的单词
if let regex = try? NSRegularExpression(pattern: #"t[^ ]+"#, options: NSRegularExpression.Options.caseInsensitive) {
let input = "this is the best test"
let matches = regex.matches(in: input, options: [], range: NSRange(location: 0, length: input.count))
for match in matches {
print((input as NSString).substring(with: match.range))
}
}
在上面的代码中,我使用了一个简单的 space 作为分隔符 (#"t[^ ]+"#
) 并且输出符合预期:
this
the
test
但是,不仅要考虑 spaces,还要考虑所有的单词边界。因此,我将 space 替换为 \b
以匹配所有边界 (#"t[^\b]+"#
)。但是,这不起作用:
this is the
t test
看来这段代码并没有寻找单词边界,而是简单地寻找b
...这是为什么?
我认为在正则表达式前后使用 #
会创建一个原始字符串,从而将 \
正确地传送到正则表达式系统。所以 #"t[^\b]+"#
应该和 "t[^\b]+"
一样并被翻译成 t[^\b]+
,不是吗?
或者单词边界运算符 \b
在 Swift 正则表达式中不可用?
编辑:
根据 ICU Documentation \b
匹配 词边界 ,因此 [^\b]
(除词边界外的任何内容)不应该是与 [^b]
相同(除了 a b 之外的任何东西),应该吗?
不过\b
好像不能套用吧?但是 \B
应该做同样的事情(除了单词边界之外的任何东西)。
所以我尝试使用 #"t\B+"#
代替。但是,这根本找不到任何匹配项。
问题仍然存在:如何在Swift NSRegularExpression中匹配单词边界?
#"t[^\b]+"#
字符串字面量导致 t[^\b]+
正则表达式,它只匹配 t
然后一个或多个字符而不是 b
字符([^\b]
在 ICU 正则表达式中等于 [^b]
。
要匹配 t
然后一个或多个单词字符(即,直到下一个最左边的单词边界),您可以使用
pattern: #"t\w+"#
其中 \w+
将匹配一个或多个单词字符。
一个[...]
是一个字符set/class。字符 class 意味着匹配 个字符 。 \b
是一个词边界只在一个字符class之外,因为词边界不是一个字符,它是匹配字符串中某个 位置 的零宽度断言。所有零宽度断言在字符 class 中都失去了它们特殊的“零宽度”含义。 [.$]
并不表示 .
或字符串结尾,它匹配 .
或 $
字符。 [.\z]
不匹配 .
或字符串的末尾,它匹配 .
或 z
因为 \
被省略,因为 \z
不是有效的转义序列。
此外,t\B+
没有什么意义,因为 \B
,还有一个 零宽度断言 ,匹配一个 位置 在不是单词边界位置的字符串中。请注意,零宽度断言不会 consume 文本,即没有文本添加到整体匹配内存缓冲区,并且正则表达式索引保持在尝试零宽度断言模式之前的位置。通过在 \B
之后添加 +
,您只需告诉正则表达式引擎匹配 t
之后的 location 这不是单词边界,因此正则表达式引擎匹配 t\B+
的方式与它是 t\B
的方式相同,即它只匹配后跟单词 char(字母、数字、连接符)的 t
。
\w
匹配(并且 消耗 )单词字符,因此如果您需要匹配(并真正得到结果)t
之后的任何字符直到第一个单词边界,你只需要使用这个 \w
模式,t\w*
或 t\w+
(如果 t
之后必须至少有一个单词字符)。
我想捕获以某个前缀开头的字符串中的所有 单词 。例如所有以 t
if let regex = try? NSRegularExpression(pattern: #"t[^ ]+"#, options: NSRegularExpression.Options.caseInsensitive) {
let input = "this is the best test"
let matches = regex.matches(in: input, options: [], range: NSRange(location: 0, length: input.count))
for match in matches {
print((input as NSString).substring(with: match.range))
}
}
在上面的代码中,我使用了一个简单的 space 作为分隔符 (#"t[^ ]+"#
) 并且输出符合预期:
this
the
test
但是,不仅要考虑 spaces,还要考虑所有的单词边界。因此,我将 space 替换为 \b
以匹配所有边界 (#"t[^\b]+"#
)。但是,这不起作用:
this is the
t test
看来这段代码并没有寻找单词边界,而是简单地寻找b
...这是为什么?
我认为在正则表达式前后使用 #
会创建一个原始字符串,从而将 \
正确地传送到正则表达式系统。所以 #"t[^\b]+"#
应该和 "t[^\b]+"
一样并被翻译成 t[^\b]+
,不是吗?
或者单词边界运算符 \b
在 Swift 正则表达式中不可用?
编辑:
根据 ICU Documentation \b
匹配 词边界 ,因此 [^\b]
(除词边界外的任何内容)不应该是与 [^b]
相同(除了 a b 之外的任何东西),应该吗?
不过\b
好像不能套用吧?但是 \B
应该做同样的事情(除了单词边界之外的任何东西)。
所以我尝试使用 #"t\B+"#
代替。但是,这根本找不到任何匹配项。
问题仍然存在:如何在Swift NSRegularExpression中匹配单词边界?
#"t[^\b]+"#
字符串字面量导致 t[^\b]+
正则表达式,它只匹配 t
然后一个或多个字符而不是 b
字符([^\b]
在 ICU 正则表达式中等于 [^b]
。
要匹配 t
然后一个或多个单词字符(即,直到下一个最左边的单词边界),您可以使用
pattern: #"t\w+"#
其中 \w+
将匹配一个或多个单词字符。
一个[...]
是一个字符set/class。字符 class 意味着匹配 个字符 。 \b
是一个词边界只在一个字符class之外,因为词边界不是一个字符,它是匹配字符串中某个 位置 的零宽度断言。所有零宽度断言在字符 class 中都失去了它们特殊的“零宽度”含义。 [.$]
并不表示 .
或字符串结尾,它匹配 .
或 $
字符。 [.\z]
不匹配 .
或字符串的末尾,它匹配 .
或 z
因为 \
被省略,因为 \z
不是有效的转义序列。
此外,t\B+
没有什么意义,因为 \B
,还有一个 零宽度断言 ,匹配一个 位置 在不是单词边界位置的字符串中。请注意,零宽度断言不会 consume 文本,即没有文本添加到整体匹配内存缓冲区,并且正则表达式索引保持在尝试零宽度断言模式之前的位置。通过在 \B
之后添加 +
,您只需告诉正则表达式引擎匹配 t
之后的 location 这不是单词边界,因此正则表达式引擎匹配 t\B+
的方式与它是 t\B
的方式相同,即它只匹配后跟单词 char(字母、数字、连接符)的 t
。
\w
匹配(并且 消耗 )单词字符,因此如果您需要匹配(并真正得到结果)t
之后的任何字符直到第一个单词边界,你只需要使用这个 \w
模式,t\w*
或 t\w+
(如果 t
之后必须至少有一个单词字符)。