Что такое граница слова в регулярных выражениях?



я использую Java regexes в Java 1.6 (в частности, для разбора числового вывода) и не могу найти точное определение 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
683   10  

10 ответов:

граница слова, в большинстве диалектов регулярных выражений, является положение между \w и \W (Не-слово char), или в начале или конце строки, если она начинается или заканчивается (соответственно) с символа слова ([0-9A-Za-z_]).

Итак, в строке "-12", это будет соответствовать ДО 1 или после 2. Тире-это не символ слова.

граница слова может находиться в одной из трех позиций:

  1. перед первым символом в строке, если первый символ является символом слова.
  2. после последнего символа в строке, если последний символ является символом слова.
  3. между двумя символами в строке, где один является символом слова, а другой не является символом слова.

символы слова являются буквенно-цифровыми; знак минус-нет. Взято из Регулярное Выражение Учебник.

граница слова-это позиция, которая либо предшествует символу слова и не сопровождается одним, либо следует за символом слова и не предшествует одному.

ознакомьтесь с документацией по граничным условиям:

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 вроде как опередил меня, поэтому он получает право голоса.

Я говорю о том, что \b-границы регулярных выражений стиля на самом деле здесь.

рассказ в том, что они условный. Их поведение зависит от того, что они рядом.

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

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

иногда это не то, что вы хотите. См. мой другой ответ для разработки.

я столкнулся с еще более серьезной проблемой при поиске текста для таких слов, как .NET,C++,C# и C. Вы могли бы подумать, что компьютерные программисты будут знать лучше, чем называть язык, для которого трудно писать регулярные выражения.

во всяком случае, это то, что я узнал (в основном изhttp://www.regular-expressions.info, что является отличным сайтом): в большинстве вариантов регулярных выражений символы, которые соответствуют короткой руке класс символов \w символы, которые рассматриваются как символы слова по границам слов. Java является исключением. Java поддерживает Unicode для \b а не \w. (Я уверен, что в то время для этого была веская причина).

The \w означает "символ слова". Он всегда соответствует символам ASCII [A-Za-z0-9_]. Обратите внимание на включение подчеркивания и цифр (но не тире!). В большинстве вкусов, которые поддерживают Unicode,\w включает в себя множество персонажей из других файлы сценариев. Существует много несоответствий о том, какие символы на самом деле включены. Буквы и цифры из алфавитных сценариев и идеограмм, как правило, включены. Знаки препинания соединителя, отличные от подчеркивания и числовых символов, которые не являются цифрами, могут быть включены или не включены. XML-схема и XPath даже включают все символы в \w. Но Java, JavaScript и PCRE соответствуют только символам ASCII с \w.

именно поэтому регулярное выражение на основе Java ищет 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));

P. S. Моя спасибо http://regexpal.com/ без кого выражения мир был бы очень несчастен!

Я считаю, что ваша проблема связана с тем, что - не является символом слова. Таким образом, граница слова будет совпадать после -, и поэтому не будет захватывать его. Границы слов совпадают перед первым и после последнего символа слова в строке, а также в любом месте, где перед ним находится символ слова или не-символ слова, а после него-наоборот. Также обратите внимание, что граница слова соответствует нулевой ширине.

одна возможная альтернатива это

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

это будет соответствовать любым числам, начиная с пробела и необязательного тире, и заканчивая границей слова. Он также будет соответствовать числу, начиная с начала строки.

в ходе обучения регулярное выражение, я действительно застрял в метасимвол, которая составляет \b. Я действительно не понимал его смысла, когда спрашивал себя:"что это такое, что это" повторно. После некоторых попыток с помощью сайте, Я наблюдаю за розовыми вертикальными черточками в каждом начале слов и в конце слов. Я хорошо понял его значение в то время. Это сейчас точно word (\w)-граница.

мой взгляд просто чрезвычайно ориентирован на понимание. Логика за этим должна быть рассмотрена из других ответов.

enter image description here

Я думаю, что это граница (т. е. следующий символ) последнего матча или начала или конца строки.

при использовании \b(\w+)+\b Это означает точное совпадение со словом, содержащим только символы слова ([a-zA-Z0-9])

в вашем случае, например, параметр \b в начале регулярного выражения будет принимать -12(С пробелом), но опять же он не примет -12(без пробелов)

для справки, чтобы поддержать мои слова:https://docs.oracle.com/javase/tutorial/essential/regex/bounds.html

Comments

    Ничего не найдено.