swift2 等价于 python 的 shlex.split 以保留引用字符串中的空格
swift2 equivalent of python's shlex.split to preserve the whitespace within quoted strings
我正在寻找一个现有的 swift2 函数来拆分空格上的字符串输入 ,同时在引用的字符串中保留空格。
我已阅读stack overflow question 25678373。我的问题似乎没有重复。
我在 cocoapods 中搜索了类似的功能。我没找到。
如果这个 shlex.split 函数在 swift2 中不存在,那么实现类似功能的有效替代方法是什么?在内部引用字符串中保留空格的同时拆分字符串的替代方法是什么?
这是我在 python 中的意思的示例:
$ python
Python 2.7.6 (default, Jun 22 2015, 18:00:18)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import shlex
>>> input=""" alpha 2 'chicken with teeth' 4 'cat with wings' 6 turkey"""
>>> results = shlex.split(input)
>>> type(results)
<type 'list'>
>>> results[0]
'alpha'
>>> results[2]
'chicken with teeth'
>>> for term in results:
... print(term)
...
alpha
2
chicken with teeth
4
cat with wings
6
turkey
>>>
正如@EricD 在给您的评论中所写,不存在这样的原生 Swift 函数。但是,您可以很容易地编写自己的此类拆分函数,例如
extension String {
func shlexSplit() -> [String] {
/* separate words by spaces */
var bar = self.componentsSeparatedByString(" ")
/* identify array idx ranges of quoted (') sets of words */
var accumulating = false
var from = 0
var joinSegments : [(Int, Int)] = []
for (i,str) in bar.enumerate() {
if str.containsString("'") {
if accumulating { joinSegments.append((from, i)) }
else { from = i }
accumulating = !accumulating
}
}
/* join matching word ranges with " " */
for (from, through) in joinSegments.reverse() {
bar.replaceRange(from...through,
with: [bar[from...through].joinWithSeparator(" ")])
}
return bar
}
}
使用示例
/* exampe usage */
let foo = "alpha 2 'chicken with teeth' 4 'cat with wings' 6 turkey"
let bar = foo.shlexSplit()
bar.forEach{ print([=11=]) }
/* alpha
2
'chicken with teeth'
4
'cat with wings'
6
turkey */
请注意,以上假定输入字符串具有匹配的引号分隔符集 '
。
'pure'swift(无基础)示例
extension String {
// split by first incidence of character
func split(c: Character)->(String,String) {
var head: String = "", tail: String = ""
if let i = characters.indexOf(c) {
let j = startIndex.distanceTo(i)
head = String(characters.prefix(j))
tail = String(characters.dropFirst(j + 1))
} else {
head = self
}
return (head, tail)
}
}
// what you are looking for
func split(str: String)->[String] {
// internal state
var state:((String,String), [String], Bool) = (str.split("'"), [], false)
repeat {
if !state.2 {
// you can define more whitespace characters
state.1
.appendContentsOf(state.0.0.characters.split{" \t\n\r".characters.contains([=10=])}
.map(String.init))
state.2 = true
} else {
state.1.append(state.0.0)
state.2 = false
}
state.0 = state.0.1.split("'")
} while !state.0.0.isEmpty
return state.1
}
用法
let str = "a 2 'b c' d ''"
dump(split(str))
/*
▿ 4 elements
- [0]: a
- [1]: 2
- [2]: b c
- [3]: d
*/
我正在寻找一个现有的 swift2 函数来拆分空格上的字符串输入 ,同时在引用的字符串中保留空格。
我已阅读stack overflow question 25678373。我的问题似乎没有重复。
我在 cocoapods 中搜索了类似的功能。我没找到。
如果这个 shlex.split 函数在 swift2 中不存在,那么实现类似功能的有效替代方法是什么?在内部引用字符串中保留空格的同时拆分字符串的替代方法是什么?
这是我在 python 中的意思的示例:
$ python
Python 2.7.6 (default, Jun 22 2015, 18:00:18)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import shlex
>>> input=""" alpha 2 'chicken with teeth' 4 'cat with wings' 6 turkey"""
>>> results = shlex.split(input)
>>> type(results)
<type 'list'>
>>> results[0]
'alpha'
>>> results[2]
'chicken with teeth'
>>> for term in results:
... print(term)
...
alpha
2
chicken with teeth
4
cat with wings
6
turkey
>>>
正如@EricD 在给您的评论中所写,不存在这样的原生 Swift 函数。但是,您可以很容易地编写自己的此类拆分函数,例如
extension String {
func shlexSplit() -> [String] {
/* separate words by spaces */
var bar = self.componentsSeparatedByString(" ")
/* identify array idx ranges of quoted (') sets of words */
var accumulating = false
var from = 0
var joinSegments : [(Int, Int)] = []
for (i,str) in bar.enumerate() {
if str.containsString("'") {
if accumulating { joinSegments.append((from, i)) }
else { from = i }
accumulating = !accumulating
}
}
/* join matching word ranges with " " */
for (from, through) in joinSegments.reverse() {
bar.replaceRange(from...through,
with: [bar[from...through].joinWithSeparator(" ")])
}
return bar
}
}
使用示例
/* exampe usage */
let foo = "alpha 2 'chicken with teeth' 4 'cat with wings' 6 turkey"
let bar = foo.shlexSplit()
bar.forEach{ print([=11=]) }
/* alpha
2
'chicken with teeth'
4
'cat with wings'
6
turkey */
请注意,以上假定输入字符串具有匹配的引号分隔符集 '
。
'pure'swift(无基础)示例
extension String {
// split by first incidence of character
func split(c: Character)->(String,String) {
var head: String = "", tail: String = ""
if let i = characters.indexOf(c) {
let j = startIndex.distanceTo(i)
head = String(characters.prefix(j))
tail = String(characters.dropFirst(j + 1))
} else {
head = self
}
return (head, tail)
}
}
// what you are looking for
func split(str: String)->[String] {
// internal state
var state:((String,String), [String], Bool) = (str.split("'"), [], false)
repeat {
if !state.2 {
// you can define more whitespace characters
state.1
.appendContentsOf(state.0.0.characters.split{" \t\n\r".characters.contains([=10=])}
.map(String.init))
state.2 = true
} else {
state.1.append(state.0.0)
state.2 = false
}
state.0 = state.0.1.split("'")
} while !state.0.0.isEmpty
return state.1
}
用法
let str = "a 2 'b c' d ''"
dump(split(str))
/*
▿ 4 elements
- [0]: a
- [1]: 2
- [2]: b c
- [3]: d
*/