如何只搜索Swift字符串中的整个单词

时间:2016-12-22 09:55:22

标签: regex swift

我有这个NS搜索表达式。 searchString 传入一个String,我想在 baseString 中搜索并突出显示。但是,如果我搜索“ I '一个' '在单词' h i de'例如突出显示。

我已经看到我可以使用\b来搜索整个单词,但我无法看到我将其添加到表达式中的位置。所以只突出整个单词。

另一个例子可能是我的 baseString 包含'他的故事是历史'我用 searchString 来搜索他的'它将突出显示他的保守党。

let regex = try! NSRegularExpression(pattern: searchString as! String,options: .caseInsensitive)

for match in regex.matches(in: baseString!, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: (baseString?.characters.count)!)) as [NSTextCheckingResult] {
    attributed.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range)
}

2 个答案:

答案 0 :(得分:5)

您可以从searchString

轻松创建正则表达式模式
let baseString = "His story is history"
let searchString = "his" //This needs to be a single word
let attributed = NSMutableAttributedString(string: baseString)

//Create a regex pattern matching with word boundaries
let searchPattern = "\\b"+NSRegularExpression.escapedPattern(for: searchString)+"\\b"

let regex = try! NSRegularExpression(pattern: searchPattern, options: .caseInsensitive)

for match in regex.matches(in: baseString, range: NSRange(0..<baseString.utf16.count)) {
    attributed.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range)
}

一些意见:

  • 假设上面的代码中baseStringsearchString是非可选的String,如果没有,请在搜索之前尽快制作。

  • 空的OptionSet由[]表示,因此代码中的options: NSRegularExpression.MatchingOptions()可以简化为option: [],并且它是options:参数的默认值matches方法,您无需指定。

  • NSRegularExpression根据String的UTF-16表示获取并返回范围。您不应使用characters.count制作NSRange,而是使用utf16.count

  • matches(in:range:)的返回类型声明为[NSTextCheckingResult],您无需投射。

答案 1 :(得分:2)

<强>更新

我想到了比我之前的答案更好的解决方案,所以我更新了它。对于任何喜欢这样的人来说,原始答案都会随之而来。

"(?<=[^A-Za-z0-9]|^)[A-Za-z0-9]+(?=[^A-Za-z0-9]|$)"

在我要匹配的单词之前,(?<=[^A-Za-z0-9]|^)分解此表达式,检查任何非字母数字或行^的起始位置。 [A-Za-z0-9]+?匹配任何字母数字字符,并且至少需要一个与+匹配的字符。在{I}匹配后,(?=[^A-Za-z0-9]|$)会检查另一个非字母数字或行尾$。因此,该表达式将匹配任何字母数字。要排除仅匹配字母的数字,只需从表达式中删除0-9,如

"(?<=[^A-Za-z]|^)[A-Za-z]+(?=[^A-Za-z]|$)"

对于用法,将中心匹配表达式替换为匹配的单词,如:

"(?<=[^A-Za-z]|^)\(searchString)(?=[^A-Za-z]|$)"

旧答案

我之前尝试过使用它,它找到用空格分隔的每个字符串。应该做你需要的事情

"\\s[a-zA-Z1-9]*\\s"

更改[a-zA-Z1-9] *以匹配您要搜索的内容,在您的情况下将原始搜索字符串与

相匹配
let regex = try! NSRegularExpression(pattern: "\\s\(searchString)\\s" ,options: .caseInsensitive)    

作为补充答案,\\s将包含单词前后的空格。我添加了一个检查来排除空格,如果它变得更有用,模式就像:

"(?<=\\s)[A-Za-z0-9]*(?=\\s)"

同样,替换[A-Za-z0-9]*,用您需要的搜索字符串搜索所有单词。

注意,(?<=\\s)检查单词之前的空白但不包括空格,(?=\\s)检查后面的空格,也不包括空格。与上面的原始答案相比,这在大多数情况下都会更好用,因为没有额外的空格。