Golang

2015-12-06 9 views
7
में झंडे और तर्क में एक कमांड लाइन स्ट्रिंग पार्स

मैं एक पैकेज है कि -v --format "some example" -i test के रूप में एक स्ट्रिंग इस तरह लेने के लिए और तार का एक टुकड़ा में उसे पार्स हैं, उद्धरण, रिक्त स्थान, आदि से निपटने के ठीक से तलाश कर रहा हूँ:Golang

-v 
--format 
some example 
-i 
test 

मैंने अंतर्निहित flag पैकेज के साथ-साथ गिथब पर अन्य ध्वज हैंडलिंग पैकेजों की जांच की है, लेकिन इनमें से कोई भी कच्चे स्ट्रिंग को टोकन में पार्स करने के इस विशेष मामले को संभालने के लिए प्रतीत नहीं होता है। इसे स्वयं करने की कोशिश करने से पहले मैं एक पैकेज की तलाश करूँगा क्योंकि मुझे यकीन है कि हैंडल करने के लिए बहुत से विशेष मामले हैं।

कोई सुझाव?

+0

में विभाजित किया जाएगा यह वही खोल करता है का एक मिश्रण (उद्धृत स्ट्रिंग समूह) और GNU विकल्प पार्स उपकरण (फैले होना आर्ग और झंडे के विशेष व्यवहार, और अलग अलग लंबा है/लघु ध्वज प्रारूप)। मुझे पैकेज में इन्हें जोड़ने वाले किसी के बारे में पता नहीं है। – JimB

+0

एक त्वरित हैक होगा (यदि आप जिस तरह से आप इनपुट प्रदान बदलने के लिए लचीला कर रहे हैं) (कृपया 'flag' पैकेज के दस्तावेज़ देखें): \t \t सेट: = & flag.FlagSet {} \t \t वी: = सेट .Bool ("v", false, "") \t प्रारूप: = सेट। स्ट्रिंग ("प्रारूप", "", "") \t i: = set.String ("i", "", "") \t \t सेट। पर्स ([] स्ट्रिंग {'-v',' --format = "कुछ उदाहरण" ',' -i = test'}) \t के लिए, v: = range set.Args() { \t \t log.Println (कश्मीर, वी) \t} \t \t log.Printf ("v =% वी प्रारूप =% vi =% वी", * वी, * प्रारूप, * i) –

+0

मैं अगर यकीन नहीं है मै समझता हुँ। क्या आप कुछ ऐसा करने की योजना बना रहे हैं: 'cmd -v --format "कुछ उदाहरण" -i test'? यदि ऐसा है, तो आप 'os.Args' से सभी तर्कों को पकड़ सकते हैं। – 425nesp

उत्तर

1

जानकारी के लिए इस समारोह मैं बना दी है।

यह अपने तर्कों में एक कमांड बांट देता है। उदाहरण के लिए, cat -v "some file.txt", ["cat", "-v", "some file.txt"] वापस आ जाएगा।

यह भी सही ढंग से बच गए हैंडल वर्ण, विशेष रूप से रिक्त स्थान। तो cat -v some\ file.txt भी सही ढंग से ["cat", "-v", "some file.txt"]

func parseCommandLine(command string) ([]string, error) { 
    var args []string 
    state := "start" 
    current := "" 
    quote := "\"" 
    escapeNext := true 
    for i := 0; i < len(command); i++ { 
     c := command[i] 

     if state == "quotes" { 
      if string(c) != quote { 
       current += string(c) 
      } else { 
       args = append(args, current) 
       current = "" 
       state = "start" 
      } 
      continue 
     } 

     if (escapeNext) { 
      current += string(c) 
      escapeNext = false 
      continue 
     } 

     if (c == '\\') { 
      escapeNext = true 
      continue 
     } 

     if c == '"' || c == '\'' { 
      state = "quotes" 
      quote = string(c) 
      continue 
     } 

     if state == "arg" { 
      if c == ' ' || c == '\t' { 
       args = append(args, current) 
       current = "" 
       state = "start" 
      } else { 
       current += string(c) 
      } 
      continue 
     } 

     if c != ' ' && c != '\t' { 
      state = "arg" 
      current += string(c) 
     } 
    } 

    if state == "quotes" { 
     return []string{}, errors.New(fmt.Sprintf("Unclosed quote in command line: %s", command)) 
    } 

    if current != "" { 
     args = append(args, current) 
    } 

    return args, nil 
}