如何搜索在字符串的特定索引之前开始的正则表达式匹配?
How can I search for a Regular Expression match that begins before a certain index of a string?
假设我有一个正则表达式
let regexString = "\s{1,3}(---+)\s*"
let regex = try? NSRegularExpression(pattern: regexString)
和一个字符串
let string = "Space --- the final frontier --- these are the voyages..."
并且让我们进一步假设该字符串 确实 长并且在省略号 (...
) 之后继续超过数千个字符。
现在我想找到正则表达式 regex
的第一个匹配项,但出于效率原因,我想在某个索引 后停止搜索。
示例:
index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
string: S p a c e - - - t h e f i n a l f r o n t i e r
range: + + + + + + + + + + + + + + + ⬆︎ - - - - - - - - - - - -
max
这意味着我只在字符串中搜索正则表达式匹配 that starts before index 15.
上述行为不同于仅搜索字符串的一个子范围。原因如下:
✅ 应匹配:
以下示例应在 [5–9] 范围内生成匹配项,因为匹配项在最大索引 (= 7) 之前开始。
index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
string: S p a c e - - - t h e f i n a l f r o n t i e r
range: + + + + + + + ⬆︎ - - - - - - - - - - - - - - - - - - - -
max
❎ 应该,但不匹配:
如果我只搜索最大索引 (= 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 开始,您的原始表达式将匹配,这是您的 最大值。不同之处在于整个匹配包含那些可选字符,但第一个捕获组将只包含您要查找的破折号。
我在操场上使用以下代码来测试新表达式:
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")
}
运行 上面的代码显示了以下结果:
Whole regex match starts at index: 0
Whole match: Space ---
Capture group start at index: 6
Capture group string: ---
如果string
是这样改变的:let string = "The space --- the final frontier --- these are the ...
结果是:
No matches
因为 \s{1,3}
从索引 10 开始。
希望这对你有用。
假设我有一个正则表达式
let regexString = "\s{1,3}(---+)\s*"
let regex = try? NSRegularExpression(pattern: regexString)
和一个字符串
let string = "Space --- the final frontier --- these are the voyages..."
并且让我们进一步假设该字符串 确实 长并且在省略号 (...
) 之后继续超过数千个字符。
现在我想找到正则表达式 regex
的第一个匹配项,但出于效率原因,我想在某个索引 后停止搜索。
示例:
index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
string: S p a c e - - - t h e f i n a l f r o n t i e r
range: + + + + + + + + + + + + + + + ⬆︎ - - - - - - - - - - - -
max
这意味着我只在字符串中搜索正则表达式匹配 that starts before index 15.
上述行为不同于仅搜索字符串的一个子范围。原因如下:
✅ 应匹配:
以下示例应在 [5–9] 范围内生成匹配项,因为匹配项在最大索引 (= 7) 之前开始。
index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
string: S p a c e - - - t h e f i n a l f r o n t i e r
range: + + + + + + + ⬆︎ - - - - - - - - - - - - - - - - - - - -
max
❎ 应该,但不匹配:
如果我只搜索最大索引 (= 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 开始,您的原始表达式将匹配,这是您的 最大值。不同之处在于整个匹配包含那些可选字符,但第一个捕获组将只包含您要查找的破折号。
我在操场上使用以下代码来测试新表达式:
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")
}
运行 上面的代码显示了以下结果:
Whole regex match starts at index: 0
Whole match: Space ---
Capture group start at index: 6
Capture group string: ---
如果string
是这样改变的:let string = "The space --- the final frontier --- these are the ...
结果是:
No matches
因为 \s{1,3}
从索引 10 开始。
希望这对你有用。