Mi información de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
¿En expresiones regulares? Puede representar cantidad, 0 o 1 veces, equivalente a {0, 1}, o puede usarse como un carácter especial para representar otros significados.
? seguido de otros calificadores de cantidad indica una coincidencia no codiciosa, es decir, que coincide con la cadena más corta posible que se busca.
Veamos un ejemplo:
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("a.*?");
- Matcher matcher = pattern.matcher("abcabc");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- }
- }
Salida después de la ejecución: abcabc
¿No es el partido más corto? ¿Por qué fracasó?
En realidad, esto involucra las reglas de coincidencia no codiciosa:Para una coincidencia no codiciosa, la ruta más corta coincide antes de la siguiente regla. Si no hay una regla siguiente, se procesa como una coincidencia codiciosa.
Es decir, si solo aparece "a.*?", aún se procesará según la coincidencia codiciosa.
Veamos el uso correcto:
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("(a.*?)(.*)");
- Matcher matcher = pattern.matcher("afcafc");
- if (matcher.matches()) {
- System.out.println(matcher.group(0));
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2));
- }
- }
Salida después de la ejecución:
- afcafc
- a
- fcafc
Como puede ver, el primer grupo de captura captura la cadena más corta "a" y el segundo grupo de captura captura "fcafc".
Echemos un vistazo a las otras dos situaciones:
Cuando se usa en un grupo de captura, ?: se coloca antes de la expresión regular para indicar coincidencia pero no captura, es decir, este grupo de valores coincidentes no se puede obtener mediante el método de grupo.
Veamos ejemplos
- @Test
- public void test0() {
- Pattern pattern = Pattern.compile("\d{4}-(?:[a-z]+)");
- Matcher matcher = pattern.matcher("3214-opo");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1)); // 报错
- }
- }
Se informará un error al capturar a través del grupo (1), es decir, se puede coincidir pero no se puede capturar. Si ?: se elimina, se puede capturar normalmente a través del grupo (1).
(?s) activa el modo de una sola línea en el lado derecho, lo que hace que . coincida con cualquier carácter, incluido el carácter de nueva línea n.
Veamos un ejemplo:
- private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
-
-
- /**
- * 从输出结果可知,匹配到了换行符 'n'
- */
- @Test
- public void test4() {
- Pattern pattern = Pattern.compile(DEFAULT_VARIABLE_PATTERN);
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2)); // (?s) 不能作为捕获组,报错
- }
- }
Al capturar, (?s) no se puede capturar como un grupo de captura, por lo que "((?s).*)" puede capturar el grupo (1) como máximo, y se informará un error al capturar el grupo (2).
- @Test
- public void test5() {
- Pattern pattern = Pattern.compile("(.*)");
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- }
- }
Después de eliminar (? s), intente hacer coincidir "abcnsdf". Debido a que hay un carácter de nueva línea, la coincidencia no se puede completar, por lo que no se generará nada.