Java에서 문자열을 구문 분석하는 다른 방법은 무엇입니까?[닫은]

StackOverflow https://stackoverflow.com/questions/2968

  •  08-06-2019
  •  | 
  •  

문제

플레이어 명령을 분석하기 위해 저는 다음을 가장 자주 사용했습니다. 나뉘다 문자열을 구분 기호로 분할한 다음 일련의 구분 기호로 나머지를 알아내는 방법 if또는 switch예.Java에서 문자열을 구문 분석하는 다양한 방법은 무엇입니까?

도움이 되었습니까?

해결책

나는 당신이 명령 인터페이스를 가능한 한 관대하게 만들려고 노력하고 있다고 가정합니다.이 경우 다음과 유사한 알고리즘을 사용하는 것이 좋습니다.

  1. 문자열에서 읽기
    • 문자열을 토큰으로 분할
    • 사전을 사용하여 동의어를 일반적인 형식으로 변환
    • 예를 들어 'hit', 'punch', 'strike', 'kick'을 모두 'hit'으로 변환합니다.
    • 순서가 없고 포괄적인 기준으로 작업 수행
    • 정렬되지 않은 - "원숭이의 얼굴을 때린다"는 것은 "원숭이의 얼굴을 때리는 것"과 같은 의미입니다.
    • 포함한 - 명령이 "원숭이 얼굴을 때리세요"라고 가정하고 "원숭이 펀치"를 제공하는 경우 이 명령이 몇 개 일치하는지 확인해야 합니다.명령이 하나만 있는 경우 이 작업을 수행합니다.명령 우선순위를 갖는 것도 좋은 생각일 수 있으며, 일치하는 항목이 있더라도 최고의 작업을 수행합니다.

다른 팁

저는 정규 표현식을 정말 좋아합니다.명령 문자열이 매우 간단하다면 수동으로 구문 분석하는 데 몇 페이지의 코드가 필요할 수 있는 몇 가지 정규식을 작성할 수 있습니다.

확인해 보시는 걸 추천드려요 http://www.regular-expressions.info 정규식에 대한 좋은 소개와 Java에 대한 구체적인 예를 보려면

수동으로 구문 분석하는 것은 매우 재미 있습니다 ...처음에는 :)

실제로 명령이 그다지 복잡하지 않은 경우 명령줄 해석기에서 사용되는 것과 동일한 방식으로 처리할 수 있습니다.사용할 수 있는 라이브러리 목록은 다음과 같습니다. http://java-source.net/open-source/command-line.내 생각엔 당신이 시작할 수 있을 것 같아요 아파치 커먼즈 CLI 또는 args4j (주석을 사용합니다).문서화도 잘 되어 있고 사용도 매우 간단합니다.자동으로 구문 분석을 처리하며 사용자가 해야 할 유일한 작업은 객체의 특정 필드를 읽는 것입니다.

더 정교한 명령이 있다면 공식적인 문법을 만드는 것이 더 나은 생각일 것입니다.그래픽 편집기, 디버거, 문법 해석기를 갖춘 아주 좋은 라이브러리가 있습니다.그것은 ~라고 불린다 ANTLR (그리고 편집자는 ANTLRWorks) 무료입니다. 몇 가지 예제 문법과 튜토리얼도 있습니다.

나는 볼 것이다 자바 마이그레이션 ~의 조크, 단순한 쪽으로 기울다 자연어 처리기 (이 링크에서) 다음과 같은 (토큰화 또는 ​​정규식에 의해 구동됨):

    public static boolean simpleNLP( String inputline, String keywords[])
    {
        int i;
        int maxToken = keywords.length;
        int to,from;
        if( inputline.length() = inputline.length()) return false; // check for blank and empty lines
        while( to >=0 )
        {
            to = inputline.indexOf(' ',from);
            if( to > 0){
                lexed.addElement(inputline.substring(from,to));
                from = to;
                while( inputline.charAt(from) == ' '
                && from = keywords.length) { status = true; break;}
            }
        }
        return status;
    }

...

프로그래머에게 Zork를 다시 볼 이유를 제공하는 것은 내 책에서 좋은 내용입니다. Grues를 조심하세요.

...

Sun 자체에서는 StringTokenizer를 사용하지 않고 대신 String.spilt 메서드를 사용할 것을 권장합니다.

Pattern 클래스도 살펴보고 싶을 것입니다.

ANTLR/ANTLRWorks에 대한 또 다른 투표입니다.실제로 명령을 실행하기 위한 Java 코드가 포함된 버전과 문법이 포함되지 않은 버전(문법만 포함된 버전)의 두 가지 파일 버전을 생성하면 언어의 실행 가능한 사양을 갖게 되며 이는 테스트에 적합하고 문서화에 도움이 됩니다. , 이식하기로 결정한 경우 시간을 크게 절약할 수 있습니다.

이것이 명령줄을 구문 분석하는 것이라면 다음을 사용하는 것이 좋습니다. 커먼즈 CLI.

Apache Commons CLI 라이브러리는 명령줄 인터페이스 처리를 위한 API를 제공합니다.

노력하다 JavaCC Java용 파서 생성기.

언어 해석을 위한 많은 기능이 있으며 Eclipse에서 잘 지원됩니다.

@CodingTheWheel 여기에 코드를 정리하고 Eclipse를 통해(Ctrl 키+옮기다+에프) 그리고 여기에 다시 삽입되었습니다 :)

각 줄 앞의 공백 4개를 포함합니다.

public static boolean simpleNLP(String inputline, String keywords[]) {
    if (inputline.length() < 1)
        return false;

    List<String> lexed = new ArrayList<String>(); 
    for (String ele : inputline.split(" ")) {
        lexed.add(ele);
    }


    boolean status = false;
    to = 0;
    for (i = 0; i < lexed.size(); i++) {
        String s = (String) lexed.get(i);
        if (s.equalsIgnoreCase(keywords[to])) {
            to++;
            if (to >= keywords.length) {
                status = true;
                break;
            }
        }
    }
    return status;
}

공백에 대한 간단한 문자열 토크나이저가 작동해야 하지만 이를 수행할 수 있는 방법은 정말 많습니다.

다음은 토크나이저를 사용하는 예입니다.

String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;

if (tokens.hasMoreTokens()) {
    action = tokens.nextToken();
}

if (action != null) {
    doCommand(action, tokens);
}

그런 다음 인수에 토큰을 추가로 사용할 수 있습니다.이것은 모두 인수에 공백이 사용되지 않는다고 가정합니다 ...따라서 자신만의 간단한 구문 분석 메커니즘을 적용하고 싶을 수도 있습니다(예: 첫 번째 공백을 가져오고 작업 전에 텍스트를 사용하거나 속도 저하에 신경 쓰지 않는 경우 정규 표현식을 사용하는 등). 사용할 수 있도록 추상화하기만 하면 됩니다. 어딘가에.

명령의 구분자 문자열이 항상 동일한 문자열 또는 문자(예: ";")인 경우 SrinkTokenizer 클래스를 사용하는 것이 좋습니다.

스트링토크나이저

그러나 구분 기호가 다양하거나 복잡할 경우 1.4부터 String 클래스 자체, 메소드 분할에서 사용할 수 있는 정규 표현식을 사용하는 것이 좋습니다.java.util.regex 패키지의 Pattern 클래스를 사용합니다.

무늬

언어가 죽은 것처럼 간단하다면

동사 명사

그러면 손으로 나누는 것이 잘 작동합니다.

더 복잡하다면 ANTLR이나 JavaCC와 같은 도구를 실제로 살펴봐야 합니다.

ANTLR(v2)에 대한 튜토리얼이 있습니다. http://javadude.com/articles/antlrtut 그러면 그것이 어떻게 작동하는지에 대한 아이디어를 얻을 수 있습니다.

JCommander 아직 테스트해보지는 않았지만 꽤 괜찮은 것 같습니다.

텍스트에 구분 기호가 포함된 경우 다음을 수행할 수 있습니다. split 방법.
텍스트에 불규칙한 문자열이 포함되어 있으면 다른 형식을 사용해야 합니다. regular expressions.

분할 메소드는 문자열을 지정된 하위 문자열 표현식의 배열로 분할할 수 있습니다. regex.두 가지 형식의 주장은 다음과 같습니다.나뉘다 (String regex) 및 분할(String regex, int limit), 이는 (String regex)은 실제로 분할(문자열 정규식, int 제한)을 호출하여 달성합니다. 한도는 0입니다.그런 다음 한도> 0 그리고 한도 <0 무엇을 나타내는가?

jdk 설명했다:언제 한도> 0 하위 배열 길이는 최대 제한까지 가능합니다. 즉, 가능하다면 제한-1 하위 문자열로 남아 있는 하위 분할(문자에 문자열 분할 끝이 있는 제한 1회 제외)

한도 <0 배열 길이에 제한이 없음을 나타냅니다.

한도 = 0 문자열의 끝에서 빈 문자열은 잘립니다.StringTokenizer 클래스는 호환성상의 이유로 보존된 레거시 클래스이므로 String 클래스의 분할 메소드를 사용해야 합니다.인용하다 링크

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top