2013-05-23 21 views
6

Jaki jest zalecany sposób analizowania powłoki w stylu Java w Javie. Nie mam tu na myśli przetwarzania opcji, gdy są już w formie tablicy (np. Obsługa "-x" itp.), Jest już mnóstwo pytań i odpowiedzi na ten temat.Podział wiersza polecenia w Javie

Nie, chodzi mi o podzielenie pełnego ciągu poleceń na "tokeny". Trzeba przekonwertować ciąg znaków takich jak:

user 123712378 suspend "They are \"bad guys\"" Or\ are\ they? 

... do listy/tablicy:

user 
123712378 
suspend 
They are "bad guys" 
Or are they? 

Jestem obecnie tylko ten podział na białe znaki, ale to oczywiście nie może obsłużyć cudzysłów i spacji.

(obsługa Cytat jest najważniejsze Escaped obowiązuje byłoby miło-to-have.)

Uwaga: My polecenia ciąg jest wejście z interfejsem WWW shell-podobne. To nie jest zbudowany z main(String[] args)

+0

Czy większość z tych bibliotek wiersza poleceń nie rozwiązała tego problemu? Możesz po prostu spojrzeć na ich źródło. –

+1

@tieTYT O ile mi wiadomo, te biblioteki zajmują się tylko argumentami, które zostały rozdzielone przez powłokę. Są one przeznaczone do budowania poleceń, a nie powłok. –

+0

Jak podzieliłbyś następujące rzeczy: 'To jest" przykład "'. To znaczy. jak potraktujesz początkowy cudzysłów poprzedzony spoza białej spacji? –

Odpowiedz

1

To, czego potrzebujesz, to implementacja skończonego automatu. Będziesz musiał przeczytać ciąg znaków po znaku i znaleźć następny stan w zależności od następnego lub poprzedniego znaku.
Na przykład: " oznacza początek ciągu znaków, ale jeśli jest poprzedzony numerem \ pozostawia niezmieniony stan bieżący i odczytuje go do następnego tokena, który przeniesie Cię do następnego stanu.
tj. zasadniczo w swoim przykładzie trzeba

read string -> read number 
    ^- - - | 

Ty oczywiście musiałby zdefiniować wszystkie stany i znaków specjalnych, które wpływają lub nie wpływają na stan.
Szczerze mówiąc nie jestem pewien, dlaczego chciałbyś zapewnić taką funkcjonalność dla użytkownika końcowego.
Tradycyjnie wszystkie programy cli akceptują dane wejściowe w standardowym formacie -x or --x or --x=s itp.
Format ten jest dobrze znany typowemu użytkownikowi i jest prosty do wdrożenia i przetestowania jako poprawny.
Tradycyjnie, jeśli wymagane jest wprowadzenie bardziej "elastycznego" wejścia dla użytkownika, najlepiej jest zbudować graficzny interfejs użytkownika. Właśnie to sugerowałbym.

+2

Cóż, jest to dość łatwe do zbudowania (i miałem w przeszłości, w innych sytuacjach), ale miałem nadzieję, że jakaś biblioteka już to naprawiła. Jeśli chodzi o powód, nie jestem juistem budującym same komendy (to gdzie -x i takie, i mogą to zrobić w mojej aplikacji), ale najpierw buduję samą powłokę, gdzie zaawansowani użytkownicy wpisują ciągi poleceń za pośrednictwem interfejs sieciowy. –

+0

Być może jest biblioteka na to, co chcesz, ale nie jestem świadomy, który sugeruje. Ale jeśli masz zamiar zbudować taką powłokę i wdrożenie jest łatwe do zbudowania, jak mówisz, polecam go zbudować , niż zależą od innej biblioteki, jak można budować, aby dodać rzeczy w razie potrzeby (więcej/mniej funkcji, debugowanie itp.) – Cratylus

0

Budowanie args [] Powrót do łańcucha, a następnie tokenize użyciu wyrażenia regularnego:

public static void main(String[] args) { 
    String commandline = ""; 
    for(String arg : args) { 
     commandline += arg; 
     commandline += " "; 
    } 
    System.out.println(commandline); 

    List<String> list = new ArrayList<String>(); 
    Matcher m = Pattern.compile("([^\"]\\S*|\".+?\")\\s*").matcher(commandline); 
    while (m.find()) 
     list.add(m.group(1)); // Add .replace("\"", "") to remove surrounding quotes. 


    System.out.println(list); 
} 

Dalsza część wziąłem od here.

0

ArgumentTokenizer z DrJava parsuje linię poleceń w sposób, w jaki Bourne shell i jego pochodne robią.

Właściwie obsługuje wyjścia, więc bash -c 'echo "\"escaped '\''single'\'' quote\""' zostaje trafiony do [bash, -c, echo "\"escaped 'single' quote\""].