Должен ли я иметь возможность заключать в кавычки начальный или конечный знак доллара ($) внутри границы слова в регулярном выражении Java? - PullRequest
1 голос
/ 23 июля 2010

У меня возникают проблемы с получением регулярных выражений с ведущими / конечными $ для соответствия в Java (1.6.20).

Из этого кода:

System.out.println( "$40".matches("\\b\\Q$40\\E\\b") );
System.out.println( "$40".matches(".*\\Q$40\\E.*") );
System.out.println( "$40".matches("\\Q$40\\E") );
System.out.println( " ------ " );
System.out.println( "40$".matches("\\b\\Q40$\\E\\b") );
System.out.println( "40$".matches(".*\\Q40$\\E.*") );
System.out.println( "40$".matches("\\Q40$\\E") );
System.out.println( " ------ " );
System.out.println( "4$0".matches("\\b\\Q4$0\\E\\b") );
System.out.println( "40".matches("\\b\\Q40\\E\\b") );

Я получаю этирезультаты:

false
true
true
 ------ 
false
true
true
 ------ 
true
true

Кажется, что проблема в ложном начале в первых двух блоках.Таким образом, начальный / конечный знак $ (знак доллара) неправильно подобран в контексте маркера \ b (границы слова).

Истинные результаты в блоках показывают, что это не сам знак доллара в кавычках, так как замена \ b на. * или удаление всего вместе дает желаемый результат.

Последние два "истинных" результата показывают, что проблема заключается не в внутренних кавычках $, ни в совпадении границ слов (\ b) в выражении в кавычках "\ Q ... \ E".

Это ошибка Java или я что-то упустил?

Ответы [ 2 ]

3 голосов
/ 23 июля 2010

Это потому, что \b соответствует границам слова. И позиция непосредственно перед или после символа $ не обязательно считается границей слова.

Граница слова - это позиция между \w и \W, а $ не является частью \w. На примере строки «bla $» границы слова:

" b l a $ "
 ^----------- here

" b l a $ "
       ^----- here

" b l a $ "
         ^--- but not here
1 голос
/ 13 августа 2010

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

\b фактически был виновником.

Один из выводов может состоять в том, что для чего угодно, кроме самого элементарного (то есть ASCII) использования, встроенные удобные выражения из Java фактически бесполезны. Например. \w соответствует только символам ASCII, \b основано на этом и т. Д.

FWIW, мой RegExp оказался:

   (?:^|[\p{P}\p{Z}])(\QThe $earch Term\E)(?:[\p{P}\p{Z}]|$)

где The $earch Term - текст, который я пытаюсь найти.

\p{} - это категории Unicode. По сути, я разбиваю свое слово на любом символе в символьных категориях Юникода (P) или Разделителя (Z). Кроме того, учитываются начало и конец ввода (с ^ и $), а граничные маркеры помечаются как группы без захвата (биты (?:...)), в то время как фактический поисковый термин указан с \Q и \E & помещены в соответствующую группу.

...