2016-04-03 70 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 
*/ 
相關問題