2016-04-03 23 views
0

我正在寻找一个现有的swift2函数来分割空白字符串输入,同时在引用字符串中保留空白。我已阅读stack overflow question 25678373。我的问题似乎并不重复。swift2相当于python的shlex.split来保留引用字符串中的空白

我在cocoapods中搜索了类似的功能。我没有找到它。

如果这个shlex.split函数在swift2中不存在,那么完成类似工作的有效替代方法是什么?在保留内部引用字符串中的空白的同时拆分字符串的另一种方法是什么?

下面是我在蟒蛇的意思是一个例子:

$ 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 
>>> 
+0

'我正在寻找一个现有swift2功能[...]'没有这样的功能Swift标准库。 – Moritz

+1

顺便说一下,[shlex.split的源代码](http://scons.org/doc/1.3.1/HTML/scons-api/SCons.compat._scons_shlex-pysrc.html)相当复杂,它使用词法分析器来实现这个任务。 – Moritz

回答

2

由于@EricD写在他的评论给你,不存在这样的原生斯威夫特功能。但是,您可以很轻松地编写您自己的这种分割功能,例如

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($0) } 
/* alpha 
2 
'chicken with teeth' 
4 
'cat with wings' 
6 
turkey */ 

注意上面假定输入字符串具有匹配的套报价的定界符'

0

'纯' 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($0)} 
        .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 
*/ 
相关问题