2016-04-03 7 views
0

空白の文字列を空白に分割する既存のswift2関数を探していますが、同時に空白をのまま引用符で囲んでいます。swift2引用符で囲まれた文字列内の空白を保存するためのshlex.split相当

私はstack overflow question 25678373と読みました。私の質問は重複しているようには見えません。

ココアポッドで同様の機能を検索しました。私はそれを見つけられませんでした。

この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 
>>> 
+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 
*/ 
関連する問題