program story

정규식에서 단어 경계는 무엇입니까?

inputbox 2020. 8. 18. 07:42
반응형

정규식에서 단어 경계는 무엇입니까?


Java 1.6 (특히 숫자 출력을 구문 분석하기 위해)에서 Java 정규식을 사용하고 있으며 \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 Tutorial 에서 가져 왔습니다 .


단어 경계는 단어 문자가 앞에 나오고 뒤에 하나가 나오지 않거나 뒤에 단어 문자가 있고 앞에 하나가없는 위치입니다.


\b실제로 여기 에 어떤 스타일의 정규식 경계가 있는지에 대해 이야기 합니다 .

짧은 이야기는 그들이 조건 적이라는 것 입니다. 그들의 행동은 그들이 옆에있는 것에 달려 있습니다.

# 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/essential/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가 나를 펀치로이긴 것 같아서 그는 찬성표를 얻었습니다.


즉 원하는 텍스트를 검색 할 때 나는 더 악화 문제로 실행 .NET, C++, C#,와 C. 정규식을 작성하기 어려운 언어를 명명하는 것보다 컴퓨터 프로그래머가 더 잘 알고 있다고 생각할 것입니다.

어쨌든, 이것은 내가 찾은 것입니다 (대부분 http://www.regular-expressions.info 에서 요약 하면 훌륭한 사이트입니다). 대부분의 정규식에서 속기 문자 클래스와 일치하는 문자 \w는 단어 경계에 의해 단어 문자로 처리되는 문자. Java는 예외입니다. 자바는 유니 코드를 지원 \b하지만 대한 \w. (당시 그럴만 한 이유가 있었다고 확신합니다).

The \w stands for "word character". It always matches the ASCII characters [A-Za-z0-9_]. Notice the inclusion of the underscore and digits (but not dash!). In most flavors that support Unicode, \w includes many characters from other scripts. There is a lot of inconsistency about which characters are actually included. Letters and digits from alphabetic scripts and ideographs are generally included. Connector punctuation other than the underscore and numeric symbols that aren't digits may or may not be included. XML Schema and XPath even include all symbols in \w. But Java, JavaScript, and PCRE match only ASCII characters with \w.

대한 정규식 검색을 자바 기반 이유입니다 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));

PS http://regexpal.com/ 덕분에 정규식 세계가 매우 비참 할 것입니다!


In the course of learning regular expression, I was really stuck in the metacharacter which is \b. I indeed didn't comprehend its meaning while I was asking myself "what it is, what it is" repetitively. After some attempts by using the website, I watch out the pink vertical dashes at the every beginning of words and at the end of words. I got it its meaning well at that time. It's now exactly word(\w)-boundary.

My view is merely to immensely understanding-oriented. Logic behind of it should be examined from another answers.

enter image description here


I would like to explain Alan Moore's answer

A word boundary is a position that is either preceded by a word character and not followed by one, or followed by a word character and not preceded by one.

Suppose I have a string "This is a cat and she's awesome", and I am supposed to replace all occurance(s) the letter 'a' only if this letter exists at the "Boundry of a word" i.e. the letter a inside 'cat' should not be replaced.

So I'll perform regex (in Python) as

re.sub("\ba","e", myString.strip()) //replace a with e

so output will be This is e cat end she's ewesome


Word boundary \b is used where one word should be a word character and another one a non-word character. Regular Expression for negative number should be

--?\b\d+\b

check working DEMO


I believe that your problem is due to the fact that - is not a word character. Thus, the word boundary will match after the -, and so will not capture it. Word boundaries match before the first and after the last word characters in a string, as well as any place where before it is a word character or non-word character, and after it is the opposite. Also note that word boundary is a zero-width match.

One possible alternative is

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

This will match any numbers starting with a space character and an optional dash, and ending at a word boundary. It will also match a number starting at the beginning of the string.


I think it's the boundary (i.e. character following) of the last match or the beginning or end of the string.


when you use \\b(\\w+)+\\b that means exact match with a word containing only word characters ([a-zA-Z0-9])

in your case for example setting \\b at the begining of regex will accept -12(with space) but again it won't accept -12(without space)

for reference to support my words: https://docs.oracle.com/javase/tutorial/essential/regex/bounds.html

참고URL : https://stackoverflow.com/questions/1324676/what-is-a-word-boundary-in-regexes

반응형