문제

Java 1.6 (숫자 출력을 구문 분석하기 위해 Inter Alia에서 숫자 출력)에서 Java Regexes를 사용하고 있으며 정확한 정의를 찾을 수 없습니다. \b ( "단어 경계"). 나는 그것을 가정했다 -12 "정수 단어"가 될 것입니다 (일치 \b\-?\d+\b) 그러나 이것은 작동하지 않는 것 같습니다. 공간 구분 숫자와 일치하는 방법에 대해 감사합니다.

예시:

Pattern pattern = Pattern.compile("\\s*\\b\\-?\\d+\\s*");
String plus = " 12 ";
System.out.println(""+pattern.matcher(plus).matches());
String minus = " -12 ";
System.out.println(""+pattern.matcher(minus).matches());
pattern = Pattern.compile("\\s*\\-?\\d+\\s*");
System.out.println(""+pattern.matcher(minus).matches());

이것은 반환됩니다 :

true
false
true
도움이 되었습니까?

해결책

대부분의 반영 방언에서 단어 경계는 \w 그리고 \W 단어 문자로 시작하거나 끝나는 경우 문자열의 시작 또는 끝에서[0-9A-Za-z_]).

그래서 문자열에서 "-12", 그것은 1 이전 또는 2 이후에 일치합니다. 대시는 단어 문자가 아닙니다.

다른 팁

단어 경계는 세 가지 위치 중 하나에서 발생할 수 있습니다.

  1. 문자열의 첫 번째 문자 앞에, 첫 번째 문자가 단어 문자 인 경우.
  2. 문자열의 마지막 문자 후, 마지막 문자가 단어 문자 인 경우.
  3. 문자열의 두 문자 사이에서 하나는 단어 문자이고 다른 하나는 단어 문자가 아닙니다.

단어 문자는 알파 수치입니다. 마이너스 부호는 아닙니다. 가져 왔습니다 Regex 튜토리얼.

단어 경계는 단어 캐릭터가 앞서 있고 하나 뒤에는 하나가 뒤 따르거나 단어 문자가 뒤 따르는 위치입니다.

나는 무엇에 대해 이야기합니다 \b-Style Regex 경계는 실제로입니다 여기.

짧은 이야기는 그것입니다 가정 어구. 그들의 행동은 그들이 옆에있는 것에 달려 있습니다.

# same as using a \b before:
(?(?=\w) (?<!\w)  | (?<!\W) )

# same as using a \b after:
(?(?<=\w) (?!\w)  | (?!\W)  )

때때로 그것은 당신이 원하는 것이 아닙니다. 정교화에 대한 나의 다른 대답을 참조하십시오.

경계 조건에 대한 문서를 확인하십시오.

http://java.sun.com/docs/books/tutorial/estential/regex/bounds.html

이 샘플을 확인하십시오.

public static void main(final String[] args)
    {
        String x = "I found the value -12 in my string.";
        System.err.println(Arrays.toString(x.split("\\b-?\\d+\\b")));
    }

인쇄하면 출력이 다음과 같습니다.

내 문자열에서 가치를 찾았습니다.

이것은 "-"캐릭터가 단어의 문자로 간주되지 않기 때문에 단어의 경계에있는 것으로 선택되지 않았 음을 의미합니다. @Brianary Kinda가 나를 펀치로이기는 것처럼 보이기 때문에 그는 투표권을 얻습니다.

나는 같은 단어를 검색 할 때 더 나쁜 문제를 일으켰습니다. .NET, C++, C#, 그리고 C. 컴퓨터 프로그래머는 정기적 인 표현을 작성하기 어려운 언어의 이름을 지정하는 것보다 더 잘 알고 있다고 생각할 것입니다.

어쨌든, 이것은 내가 알게 된 것입니다 (주로 요약 http://www.regular-expressions.info, 좋은 사이트입니다) : 대부분의 풍미에서, 짧은 캐릭터 클래스와 일치하는 캐릭터 \w 단어 경계에 의해 단어 문자로 취급되는 문자입니다. Java는 예외입니다. Java는 유니 코드를 지원합니다 \b 그러나 그렇지 않습니다 \w. (당시에는 좋은 이유가 있다고 확신합니다).

그만큼 \w "단어 문자"를 나타냅니다. 항상 ASCII 문자와 일치합니다 [A-Za-z0-9_]. 밑줄과 숫자의 포함을 주목하십시오 (대시는 아님). 유니 코드를 지원하는 대부분의 맛에서 \w 다른 스크립트의 많은 문자가 포함되어 있습니다. 어떤 문자가 실제로 포함되어 있는지에 대한 불일치가 많이 있습니다. 알파벳 스크립트와 사원 사진의 문자와 숫자가 일반적으로 포함됩니다. 숫자가 아닌 밑줄 및 숫자 기호 이외의 커넥터 구두점은 포함되지 않을 수 있습니다. XML 스키마 및 XPath에는 모든 기호를 포함시킵니다 \w. 그러나 Java, JavaScript 및 PCRE는 ASCII 문자 만 \w.

이것이 바로 Java 기반 Regex가 검색하는 이유입니다 C++, C# 또는 .NET (기간과 플러스를 탈출하는 것을 기억하더라도) \b.

참고 : 문장이 끝날 때 한 번 후에 누군가가 공간을 두지 않을 때와 같이 텍스트의 실수에 대해 무엇을 해야할지 잘 모르겠습니다. 나는 그것을 허용했지만 그것이 반드시 옳은 일이라는 것을 확신하지 못한다.

어쨌든, Java에서는 이상한 언어에 대한 텍스트를 찾고 있다면 교체해야합니다. \b 공백 및 구두점 지정자 전후. 예를 들어:

public static String grep(String regexp, String multiLineStringToSearch) {
    String result = "";
    String[] lines = multiLineStringToSearch.split("\\n");
    Pattern pattern = Pattern.compile(regexp);
    for (String line : lines) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            result = result + "\n" + line;
        }
    }
    return result.trim();
}

그런 다음 테스트 또는 주요 기능에서 :

    String beforeWord = "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|^)";   
    String afterWord =  "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|$)";
    text = "Programming in C, (C++) C#, Java, and .NET.";
    System.out.println("text="+text);
    // Here is where Java word boundaries do not work correctly on "cutesy" computer language names.  
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for .NET="+ grep("\\b\\.NET\\b", text));
    System.out.println("Should find: grep exactly for .NET="+ grep(beforeWord+"\\.NET"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for C#="+ grep("\\bC#\\b", text));
    System.out.println("Should find: grep exactly for C#="+ grep("C#"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java:grep with word boundary for C++="+ grep("\\bC\\+\\+\\b", text));
    System.out.println("Should find: grep exactly for C++="+ grep(beforeWord+"C\\+\\+"+afterWord, text));

    System.out.println("Should find: grep with word boundary for Java="+ grep("\\bJava\\b", text));
    System.out.println("Should find: grep for case-insensitive java="+ grep("?i)\\bjava\\b", text));
    System.out.println("Should find: grep with word boundary for C="+ grep("\\bC\\b", text));  // Works Ok for this example, but see below
    // Because of the stupid too-short cutsey name, searches find stuff it shouldn't.
    text = "Worked on C&O (Chesapeake and Ohio) Canal when I was younger; more recently developed in Lisp.";
    System.out.println("text="+text);
    System.out.println("Bad word boundary because of C name: grep with word boundary for C="+ grep("\\bC\\b", text));
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
    // Make sure the first and last cases work OK.

    text = "C is a language that should have been named differently.";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    text = "One language that should have been named differently is C";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    //Make sure we don't get false positives
    text = "The letter 'c' can be hard as in Cat, or soft as in Cindy. Computer languages should not require disambiguation (e.g. Ruby, Python vs. Fortran, Hadoop)";
    System.out.println("text="+text);
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

추신 감사합니다 http://regexpal.com/ 누구라도 Regex 세계가 매우 비참 할 것입니다!

정규 표현을 배우는 과정에서 나는 Metacharacter에 정말로 갇혀있었습니다. \b. 내가 스스로에게 물어 보는 동안 나는 그 의미를 이해하지 못했다 "그것이 무엇인지, 그것이 무엇인지"반복적으로. 사용한 후 웹 사이트, 나는 단어의 시작과 단어 끝에서 분홍색 수직 대시를 지켜 보았습니다. 나는 그 당시에 그것을 잘 받았다. 지금은 정확히입니다 단어(\w)-경계.

내 견해는 단지 엄청나게 이해되는 지향적입니다. 그 뒤의 논리는 다른 답변에서 검토해야합니다.

enter image description here

설명하고 싶습니다 앨런 무어대답

단어 경계는 단어 캐릭터가 앞서 있고 하나 뒤에는 하나가 뒤 따르거나 단어 문자가 뒤 따르는 위치입니다.

내가 문자열이 있다고 가정 해 봅시다 T 그리고 그녀는 wesome ", 그리고 나는이 편지가 "단어의 경계" 즉, 편지 a 내부 '고양이'를 교체해서는 안됩니다.

그래서 Regex (in 파이썬) 처럼

re.sub("\ba","e", myString.strip()) //바꾸다 a ~와 함께 e

따라서 출력이 될 것입니다 eend 그녀는 e멍청한

나는 당신의 문제가 - 단어 캐릭터가 아닙니다. 따라서 경계라는 단어는 다음에 일치합니다 -, 그리고 그것을 캡처하지 않습니다. Word 경계는 문자열의 첫 번째 단어와 마지막 단어 문자와 그 이전의 어떤 장소가 단어 문자 또는 비 단어 문자 인 곳과 반대입니다. 또한 단어 경계는 제로 폭을 일치합니다.

가능한 한 가지 대안입니다

(?:(?:^|\s)-?)\d+\b

이것은 공간 문자와 선택적 대시로 시작하여 단어 경계로 끝나는 숫자와 일치합니다. 또한 문자열의 시작 부분에서 시작하는 숫자와 일치합니다.

단어 경계 b는 한 단어가 단어 문자이고 다른 단어는 비 단어 문자 인 경우에 사용됩니다. 음수에 대한 정규 표현은이어야합니다

--?\b\d+\b

작업을 확인하십시오 데모

나는 그것이 마지막 경기의 경계 (즉, 다음과 같은 문자) 또는 문자열의 시작 또는 끝이라고 생각합니다.

당신이 사용할 때 \\b(\\w+)+\\b 그것은 단어 문자 만 포함 된 단어와 정확히 일치하는 것을 의미합니다. ([a-zA-Z0-9])

예를 들어 설정과 같은 경우 \\b Regex가 시작될 때 수락 할 것입니다 -12(공간 포함) 그러나 다시는 받아들이지 않습니다 -12(공간없이)

내 말을 뒷받침하기 위해 : https://docs.oracle.com/javase/tutorial/estential/esential/regex/bounds.html

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