swift 中的正则表达式
Regular expressions in swift
我对 swift 中的 NSRegularExpression 有点困惑,有人可以帮助我吗?
任务:1 给定 ("name","john","name of john")
那我应该得到["name","john","name of john"]
。在这里我应该避免括号。
任务:2 给定 ("name"," john","name of john")
那我应该得到["name","john","name of john"]
。在这里我应该避免括号和额外的空格,最后得到一个字符串数组。
任务:3 给定 key = value // comment
那我应该得到["key","value","comment"]
。在这里,我应该通过避免 =
和 //
来仅获取行中的字符串
我已经为任务 1 尝试了以下代码,但没有通过。
let string = "(name,john,string for user name)"
let pattern = "(?:\w.*)"
do {
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
for match in matches {
if let range = Range(match.range, in: string) {
let name = string[range]
print(name)
}
}
} catch {
print("Regex was bad!")
}
提前致谢。
Swift
中的正则表达式
这些帖子可能会帮助您探索 swift:
中的正则表达式
- How to group search regular expressions using swift?
任务 1 和 2
此表达式可能会帮助您匹配任务 1 和 2 所需的输出:
"(\s+)?([a-z\s]+?)(\s+)?"
根据Rob的建议,您可以大大减少边界,例如字符列表[a-z\s]
。例如这里,我们还可以使用:
"(\s+)?(.*?)(\s+)?"
或
"(\s+)?(.+?)(\s+)?"
简单地传递两个 " and/or space.
之间的所有内容
正则表达式
如果这不是您想要的表达方式,您可以 modify/change 在 regex101.com 中表达您的表达方式。
正则表达式电路
您还可以在 jex.im:
中可视化您的表情
JavaScript 演示
const regex = /"(\s+)?([a-z\s]+?)(\s+)?"/gm;
const str = `"name","john","name of john"
"name"," john","name of john"
" name "," john","name of john "
" name "," john"," name of john "`;
const subst = `\n`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);
任务 3
This expression可能会帮助你为第三个任务设计一个表达式:
(.*?)([a-z\s]+)(.*?)
const regex = /(.*?)([a-z\s]+)(.*?)/gm;
const str = `key = value // comment
key = value with some text // comment`;
const subst = `,`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);
用除空格外的非字母数字字符分隔字符串。然后 trim 带有空格的元素。
extension String {
func words() -> [String] {
return self.components(separatedBy: CharacterSet.alphanumerics.inverted.subtracting(.whitespaces))
.filter({ ![=10=].isEmpty })
.map({ [=10=].trimmingCharacters(in: .whitespaces) })
}
}
let string1 = "(name,john,string for user name)"
let string2 = "(name, john,name of john)"
let string3 = "key = value // comment"
print(string1.words())//["name", "john", "string for user name"]
print(string2.words())//["name", "john", "name of john"]
print(string3.words())//["key", "value", "comment"]
单一模式,适用于 test:1...3,在 Swift。
let string =
//"(name,john,string for user name)" //test:1
//#"("name"," john","name of john")"# //test:2
"key = value // comment" //test:3
let pattern = #"(?:\w+)(?:\s+\w+)*"# //Swift 5+ only
//let pattern = "(?:\w+)(?:\s+\w+)*"
do {
let regex = try NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: string, range: NSRange(0..<string.utf16.count))
let matchingWords = matches.map {
String(string[Range([=10=].range, in: string)!])
}
print(matchingWords) //(test:3)->["key", "value", "comment"]
} catch {
print("Regex was bad!")
}
让我们考虑一下:
let string = "(name,José,name is José)"
我建议使用正则表达式来查找字符串,其中:
- 它是完整字符串开头的
(
之后或逗号之后的子字符串,即查看 (?<=^\(|,)
; 的断言后面
- 是不包含
,
的子串,即[^,]+?
;
- 它是在完整字符串末尾以逗号或
)
终止的子字符串,即 (?=,|\)$)
和 的前瞻断言
- 如果你想让它跳过子字符串前后的白色 space,也加入
\s*+
。
因此:
let pattern = #"(?<=^\(|,)\s*+([^,]+?)\s*+(?=,|\)$)"#
let regex = try! NSRegularExpression(pattern: pattern)
regex.enumerateMatches(in: string, range: NSRange(string.startIndex..., in: string)) { match, _, _ in
if let nsRange = match?.range(at: 1), let range = Range(nsRange, in: string) {
let substring = String(string[range])
// do something with `substring` here
}
}
注意,我使用了 Swift 5 个扩展字符串定界符(以 #"
开头并以 "#
结尾),这样我就不必在其中转义反斜杠字符串。如果您使用的是 Swift 4 或更早版本,您需要转义那些反斜杠:
let pattern = "(?<=^\(|,)\s*+([^,]+?)\s*+(?=,|\)$)"
在理解了以上所有评论后,我在这里完成了。
let text = """
Capturing and non-capturing groups are somewhat advanced topics. You’ll encounter examples of capturing and non-capturing groups later on in the tutorial
"""
extension String {
func rex (_ expr : String)->[String] {
return try! NSRegularExpression(pattern: expr, options: [.caseInsensitive])
.matches(in: self, options: [], range: NSRange(location: 0, length: self.count))
.map {
String(self[Range([=10=].range, in: self)!])
}
}
}
let r = text.rex("(?:\w+-\w+)") // pass any rex
我对 swift 中的 NSRegularExpression 有点困惑,有人可以帮助我吗?
任务:1 给定 ("name","john","name of john")
那我应该得到["name","john","name of john"]
。在这里我应该避免括号。
任务:2 给定 ("name"," john","name of john")
那我应该得到["name","john","name of john"]
。在这里我应该避免括号和额外的空格,最后得到一个字符串数组。
任务:3 给定 key = value // comment
那我应该得到["key","value","comment"]
。在这里,我应该通过避免 =
和 //
来仅获取行中的字符串
我已经为任务 1 尝试了以下代码,但没有通过。
let string = "(name,john,string for user name)"
let pattern = "(?:\w.*)"
do {
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
for match in matches {
if let range = Range(match.range, in: string) {
let name = string[range]
print(name)
}
}
} catch {
print("Regex was bad!")
}
提前致谢。
Swift
中的正则表达式这些帖子可能会帮助您探索 swift:
中的正则表达式- How to group search regular expressions using swift?
任务 1 和 2
此表达式可能会帮助您匹配任务 1 和 2 所需的输出:
"(\s+)?([a-z\s]+?)(\s+)?"
根据Rob的建议,您可以大大减少边界,例如字符列表[a-z\s]
。例如这里,我们还可以使用:
"(\s+)?(.*?)(\s+)?"
或
"(\s+)?(.+?)(\s+)?"
简单地传递两个 " and/or space.
之间的所有内容正则表达式
如果这不是您想要的表达方式,您可以 modify/change 在 regex101.com 中表达您的表达方式。
正则表达式电路
您还可以在 jex.im:
中可视化您的表情JavaScript 演示
const regex = /"(\s+)?([a-z\s]+?)(\s+)?"/gm;
const str = `"name","john","name of john"
"name"," john","name of john"
" name "," john","name of john "
" name "," john"," name of john "`;
const subst = `\n`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);
任务 3
This expression可能会帮助你为第三个任务设计一个表达式:
(.*?)([a-z\s]+)(.*?)
const regex = /(.*?)([a-z\s]+)(.*?)/gm;
const str = `key = value // comment
key = value with some text // comment`;
const subst = `,`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);
用除空格外的非字母数字字符分隔字符串。然后 trim 带有空格的元素。
extension String {
func words() -> [String] {
return self.components(separatedBy: CharacterSet.alphanumerics.inverted.subtracting(.whitespaces))
.filter({ ![=10=].isEmpty })
.map({ [=10=].trimmingCharacters(in: .whitespaces) })
}
}
let string1 = "(name,john,string for user name)"
let string2 = "(name, john,name of john)"
let string3 = "key = value // comment"
print(string1.words())//["name", "john", "string for user name"]
print(string2.words())//["name", "john", "name of john"]
print(string3.words())//["key", "value", "comment"]
单一模式,适用于 test:1...3,在 Swift。
let string =
//"(name,john,string for user name)" //test:1
//#"("name"," john","name of john")"# //test:2
"key = value // comment" //test:3
let pattern = #"(?:\w+)(?:\s+\w+)*"# //Swift 5+ only
//let pattern = "(?:\w+)(?:\s+\w+)*"
do {
let regex = try NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: string, range: NSRange(0..<string.utf16.count))
let matchingWords = matches.map {
String(string[Range([=10=].range, in: string)!])
}
print(matchingWords) //(test:3)->["key", "value", "comment"]
} catch {
print("Regex was bad!")
}
让我们考虑一下:
let string = "(name,José,name is José)"
我建议使用正则表达式来查找字符串,其中:
- 它是完整字符串开头的
(
之后或逗号之后的子字符串,即查看(?<=^\(|,)
; 的断言后面
- 是不包含
,
的子串,即[^,]+?
; - 它是在完整字符串末尾以逗号或
)
终止的子字符串,即(?=,|\)$)
和 的前瞻断言
- 如果你想让它跳过子字符串前后的白色 space,也加入
\s*+
。
因此:
let pattern = #"(?<=^\(|,)\s*+([^,]+?)\s*+(?=,|\)$)"#
let regex = try! NSRegularExpression(pattern: pattern)
regex.enumerateMatches(in: string, range: NSRange(string.startIndex..., in: string)) { match, _, _ in
if let nsRange = match?.range(at: 1), let range = Range(nsRange, in: string) {
let substring = String(string[range])
// do something with `substring` here
}
}
注意,我使用了 Swift 5 个扩展字符串定界符(以 #"
开头并以 "#
结尾),这样我就不必在其中转义反斜杠字符串。如果您使用的是 Swift 4 或更早版本,您需要转义那些反斜杠:
let pattern = "(?<=^\(|,)\s*+([^,]+?)\s*+(?=,|\)$)"
在理解了以上所有评论后,我在这里完成了。
let text = """
Capturing and non-capturing groups are somewhat advanced topics. You’ll encounter examples of capturing and non-capturing groups later on in the tutorial
"""
extension String {
func rex (_ expr : String)->[String] {
return try! NSRegularExpression(pattern: expr, options: [.caseInsensitive])
.matches(in: self, options: [], range: NSRange(location: 0, length: self.count))
.map {
String(self[Range([=10=].range, in: self)!])
}
}
}
let r = text.rex("(?:\w+-\w+)") // pass any rex