Swift 如何搜索在字符串的某个索引之前开始的正则表达式匹配?

Swift 如何搜索在字符串的某个索引之前开始的正则表达式匹配?,swift,regex,string,nsregularexpression,Swift,Regex,String,Nsregularexpression,假设我有一个正则表达式 let regexString = "\\s{1,3}(---+)\\s*" let regex = try? NSRegularExpression(pattern: regexString) 还有一根绳子 let string = "Space --- the final frontier --- these are the voyages..." 让我们进一步假设字符串确实很长,并且在省略号(…)后面连续出现数千个字符 现在我想找到正则表达式regex的第一个匹

假设我有一个正则表达式

let regexString = "\\s{1,3}(---+)\\s*"
let regex = try? NSRegularExpression(pattern: regexString)
还有一根绳子

let string = "Space --- the final frontier --- these are the voyages..."
让我们进一步假设字符串确实很长,并且在省略号(
)后面连续出现数千个字符

现在我想找到正则表达式
regex
的第一个匹配项,但出于效率原因,我想停止搜索某个索引

例子: 这意味着我只在字符串中搜索索引15之前开始的正则表达式匹配项


上述行为不同于仅搜索字符串的子范围。原因如下:

✅ 应匹配: 以下示例应在[5–9]范围内生成匹配,因为匹配在最大索引(=7)之前开始

❎ 应匹配,但不匹配: 如果我只搜索最大索引(=7)的子字符串,正则表达式将无法匹配,因为部分匹配将被截断

index:  0  1  2  3  4  5  6  7  
string: S  p  a  c  e     -  -  
range:  +  +  +  +  +  +  +  ⬆︎ 
                             max 

我怎样才能做到这一点呢?

因为您使用的是捕获组,所以我假设这就是您要查找的字符串。您可以将表达式更改为:
^.{0,6}\\s{1,3}(--+)\\s*
。我补充说:

  • ^字符串的开头
  • {0,6}以从零到六个字符进行匹配
这样更改表达式将匹配您要查找的内容,如果原始表达式最多从位置6开始,则将匹配,这是您的max。不同之处在于,整个匹配包含这些可选字符,但第一个捕获组将只包含您要查找的破折号

我在操场上使用以下代码来测试新表达式:

let regexString = "^.{0,6}\\s{1,3}(---+)\\s*"
let regex = try? NSRegularExpression(pattern: regexString)
let string = "Space --- the final frontier --- these are the voyages of the     
             starship Enterprise. Its continuing mission: to explore strange 
             new worlds. To seek out new life and new civilizations. To boldly   
             go where no one has gone before!"

let matches = regex?.matches(in: string, options: [], range: NSRange(location: 0, length: string.count))
if let firstMatch = matches?.first {
    print("Whole regex match starts at index: \(firstMatch.range.lowerBound)")
    print("Whole match: \(String(string[Range(firstMatch.range, in: string)!]))")
    print("Capture group start at index: \(firstMatch.range(at: 1).lowerBound)")
    print("Capture group string: \(String(string[Range(firstMatch.range(at: 1), in: string)!]))")
} else {
    print("No matches")
}
运行上述代码将显示以下结果:

整个正则表达式匹配从索引0开始

全场比赛:太空---

捕获组从索引开始:6

捕获组字符串:---

如果
string
是这样变化的:
let string=“空间---最后的边界---这些是…
结果是:

没有火柴

因为
\\s{1,3}
从索引10开始


希望这对你有用。

那么
firstMatch
函数呢?在你的正则表达式前面加上
\A.{0,15}?
\A.{0,7}?
或任何限制都应该是很好的答案——特别是对于我的字符串示例。;)谢谢你!我想知道为什么我没有想到这一点;我一定是不习惯正则表达式…;)
index:  0  1  2  3  4  5  6  7  
string: S  p  a  c  e     -  -  
range:  +  +  +  +  +  +  +  ⬆︎ 
                             max 
let regexString = "^.{0,6}\\s{1,3}(---+)\\s*"
let regex = try? NSRegularExpression(pattern: regexString)
let string = "Space --- the final frontier --- these are the voyages of the     
             starship Enterprise. Its continuing mission: to explore strange 
             new worlds. To seek out new life and new civilizations. To boldly   
             go where no one has gone before!"

let matches = regex?.matches(in: string, options: [], range: NSRange(location: 0, length: string.count))
if let firstMatch = matches?.first {
    print("Whole regex match starts at index: \(firstMatch.range.lowerBound)")
    print("Whole match: \(String(string[Range(firstMatch.range, in: string)!]))")
    print("Capture group start at index: \(firstMatch.range(at: 1).lowerBound)")
    print("Capture group string: \(String(string[Range(firstMatch.range(at: 1), in: string)!]))")
} else {
    print("No matches")
}