我想将文本拆分成一个数组,保持标点符号与其余单词分开,所以字符串如下:
Hello, I am Albert Einstein.
应该变成这样的数组:
["Hello", ",", "I", "am", "Albert", "Einstein", "."]
我尝试使用sting.components(separatedBy: CharacterSet.init(charactersIn: " ,;;:"))
,但此方法会删除所有标点符号,并返回如下数组:
["Hello", "I", "am", "Albert", "Einstein"]
那么,我怎样才能得到像我的第一个例子一样的数组?
答案 0 :(得分:2)
它不是很好的解决方案,但你可以尝试:
var str = "Hello, I am Albert Einstein."
var list = [String]()
var currentSubString = "";
//enumerate to get all characters including ".", ",", ";", " "
str.enumerateSubstrings(in: str.startIndex..<str.endIndex, options: String.EnumerationOptions.byComposedCharacterSequences) { (substring, substringRange, enclosingRange, value) in
if let _subString = substring {
if (!currentSubString.isEmpty &&
(_subString.compare(" ") == .orderedSame
|| _subString.compare(",") == .orderedSame
|| _subString.compare(".") == .orderedSame
|| _subString.compare(";") == .orderedSame
)
) {
//create word if see any of those character and currentSubString is not empty
list.append(currentSubString)
currentSubString = _subString.trimmingCharacters(in: CharacterSet.whitespaces )
} else {
//add to current sub string if current character is not space.
if (_subString.compare(" ") != .orderedSame) {
currentSubString += _subString
}
}
}
}
//last word
if (!currentSubString.isEmpty) {
list.append(currentSubString)
}
在Swift3中:
var str = "Hello, I am Albert Einstein."
var list = [String]()
var currentSubString = "";
//enumerate to get all characters including ".", ",", ";", " "
str.enumerateSubstrings(in: str.startIndex..<str.endIndex, options: String.EnumerationOptions.byComposedCharacterSequences) { (substring, substringRange, enclosingRange, value) in
if let _subString = substring {
if (!currentSubString.isEmpty &&
(_subString.compare(" ") == .orderedSame
|| _subString.compare(",") == .orderedSame
|| _subString.compare(".") == .orderedSame
|| _subString.compare(";") == .orderedSame
)
) {
//create word if see any of those character and currentSubString is not empty
list.append(currentSubString)
currentSubString = _subString.trimmingCharacters(in: CharacterSet.whitespaces )
} else {
//add to current sub string if current character is not space.
if (_subString.compare(" ") != .orderedSame) {
currentSubString += _subString
}
}
}
}
//last word
if (!currentSubString.isEmpty) {
list.append(currentSubString)
}
这个想法是循环所有角色并同时创建单词。单词是一组不是,
,
,.
或;
的连续字符。因此,在创建循环中的单词期间,如果我们看到其中一个字符,则我们完成当前单词,并且构造中的当前单词不为空。
要根据您的输入细分步骤:
H
(不是空格或其他终端字符)
- &GT; currentSubString =&#34; H&#34; e
(不是空格或其他终端字符)
- &GT; currentSubString =&#34;他&#34; l
(不是空格或其他终端字符)
- &GT; currentSubString =&#34; Hel&#34; l
(不是空格或其他终端字符)
- &GT; currentSubString =&#34;地狱&#34; o
(不是空格或其他终端字符)
- &GT; currentSubString =&#34;你好&#34; .
(是终端字符)
list
并重新构造下一个单词,然后list = [&#34; Hello&#34;]
如果我得到这个角色。但对于其他终端角色,我们必须保留下一个字。
(是空格字符)
list
并重新开始构建 - &gt; list = [&#34; Hello&#34;,&#34;。&#34;] 答案 1 :(得分:0)
从我的评论中解释......将regular expressions想象成一种很好地在字符串中找到模式的方法。在您的情况下,模式是单词(字母组),其中包含其他可能的符号(标点符号)。
在我的评论中加入正则表达式(我已在此处进行了扩展),例如:([,\.\:\"])*([A-Za-z0-9\']*)([,\.\:\"])*
在那里,我们有3 groups
。第一个搜索任何符号(例如前导引号)。第二个是搜索字母,数字和撇号(因为人们喜欢连接单词,比如&#34;我&#39; m&#34;)。第三组搜索任何尾随标点符号。
编辑注意:上面的组用括号(和)表示,而[和]括号表示搜索的可接受字符。因此,例如,[A-Z]
表示来自A-Z的所有大写字母都是可接受的。 [A-Za-z]
可让您同时获得上下两个,而[A-Za-z0-9]
包含0-9中的所有字母和数字。当然,有写这篇的速记版本,但是你将会发现这些版本。
所以现在我们有办法将所有单词和标点符号分开,现在你需要实际使用它,按照以下方式做一些事情:
func find(value: NSString) throws -> [NSString] {
let regex = try NSRegularExpression(pattern: "([,\\.\\:\\\"])*([A-Za-z0-9\\']*)([,\\.\\:\\\"])*") // Notice you have to escape the values in code
let results = regex.matches(in: value, range: NSRange(location: 0, length: nsString.length))
return results.map({ value.substring(with: $0.range) }).filter({ $0 != nil })
}
这应该为您提供给方法提供的String值中的每个非零组。
当然,最后一种过滤方法可能没有必要,但我对Swift处理正则表达式的方式还不够熟悉。
但这绝对应该指向正确的方向......
干杯〜