Java RegEx: В чем разница между. * И \ s \ S? - PullRequest
0 голосов
/ 05 мая 2019

Я читаю книгу или ищу в Интернете, и результат говорит, что .\n обычно равен \s\S или \d\D или \w\W, что означает весь символ. Но теперь я хочу получить сообщениеиз какой-то строки я обнаружил, что могу использовать только .\n. Что не так с моим кодом? Почему я не могу использовать выражение \s\S?

String srcMsg="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root><resultCode>00000</resultCode><resultDesc><![CDATA[00000:<ResponseClass Name=\"Response\">\n    <ResponseSubClass Name=\"attributesResponse\">\n         <ITEM>0</ITEM>\n </ResponseSubClass>\n</ResponseClass>]]></resultDesc></root>";
//The right code 
java.util.regex.Pattern pP0 = java.util.regex.Pattern.compile(".*<!\\[CDATA\\[00000:((.|\n)*)\\]\\]>.*"); 
//wrong code1 
//java.util.regex.Pattern pP0 = java.util.regex.Pattern.compile(".*<!\\[CDATA\\[00000:(\\s|\\S)*\\]\\]>.*");
//wrong code2 
//java.util.regex.Pattern pP0 = java.util.regex.Pattern.compile(".*<!\\[CDATA\\[00000:[\\w|\\W]*\\]\\]>.*");
java.util.regex.Matcher mP0= pP0.matcher(srcMsg);
if(mP0.find())
para=mP0.group(1);
int dsi3 = para.indexOf("<ITEM>") + "<ITEM>".length();
int dsi4 = para.indexOf("</ITEM>");
System.out.println(Integer.valueOf(para.substring(dsi3, dsi4)));

Ответы [ 2 ]

2 голосов
/ 05 мая 2019

По умолчанию шаблон . не соответствует терминаторам строки, т. Е. Что \R соответствует:

Любая последовательность разрыва строки Unicode, эквивалентна \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Класс символов [], который объединяет два предопределенных класса символов противника, будет соответствовать всем символам, например, [\d\D], [\h\H], [\s\S], [\v\V], [\w\W], [\p{L}\P{L}] и т. Д.

Шаблон . можно изменить, чтобы он соответствовал всем символам, установив флаг DOTALL одним из следующих способов:

// Set flag external from pattern
Pattern.compile(".", Pattern.DOTALL)

// Set flag in the pattern
Pattern.compile("(?s).")

// Set flag in part of pattern
Pattern.compile("(?s:.)")

Для вашего удобства ниже приведен javadoc флага DOTALL:

Включает режим точек.

В режиме точек все выражения . соответствует любому символу, включая терминатор строки.По умолчанию это выражение не соответствует символу конца строки.

Режим точки доступа также можно включить с помощью встроенного выражения флага (?s).(s является мнемоникой для «однострочного» режима, который называется в Perl.)

1 голос
/ 05 мая 2019

. точка соответствует всем кроме новой строки. [\S\s] это класс, который имеет
все одно и все, что не есть вещь,
результат соответствует всем символам

Код ниже ссылки на регулярные выражения группа 1.
Я считаю, что вам нужна эквивалентная группа 1 в двух других регулярных выражениях. Вот они:

1) https://regex101.com/r/Tp1k9m/1

 .* <!\[CDATA\[00000:
 (                             # (1 start)
      (?: . | \n )*            #    Should be *?
 )                             # (1 end)
 \]\]> .* 

2) https://regex101.com/r/FdoHGl/1

 .* <!\[CDATA\[00000:
 (                             # (1 start)
      (?: \s | \S )*           #    Should be *?
 )                             # (1 end)
 \]\]> .* 

3) https://regex101.com/r/t3vVcB/1

 .* <!\[CDATA\[00000:
 (                             # (1 start)
      [\w\W]*                  #    Was [\w|\W], fixed it.
                               #    Should be *?
 )                             # (1 end)
 \]\]> .* 

Обратите внимание, что в классах символов существует неявное ИЛИ
между предметами. Таким образом, вам не нужно включать или символ
там, если вы не хотите совпадать с литералом |


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

...