Regex, чтобы получать число, только если нет string раньше

У меня есть линии следующего стиля:

fecha vencimiento 20-12-2017
fecha 20-12-2017

И то, что я ищу, так это способ делать регулярное выражение, что в случае, если раньше или дату спустя появится слово vencimiento не matchee.

До настоящего времени у меня есть следующий regex, чтобы признавать даты:

(\b[0-9]{1,2}(/|-)[0-1]([0-2]*)(/|-)[0-9]{4}\b)

Но я не нахожу способ это санкционировать слова "истечения срока".

1
задан 16.01.2017, 21:39
0 ответов

Как находить дату, всякий раз когда он не находился vencimiento внутри текста?

Форма, которую он рекомендовал бы, состоит в том, чтобы использовать 2 выражения:

  1. Искать, что vencimiento не будьте в тексте (предпочтительно без регулярного выражения)

  2. Захватывать дату.

Это может быть гораздо эффективнее, чем санкционировать все внутри того же regex.


Если все же ищется реализовывать все внутри того же выражения:


Как находить дату, всякий раз когда он не находился vencimiento внутри той же линии?

^(?!.*\bvencimiento\b).*\b([0-3]?\d[-/][01]?\d[-/]\d{4})\b

Как видно, с ^ мы бросаем якорь выражение в начале линии, используем flag Pattern.MULTILINE.

Самая важная структура в этом выражении - отрицательная инспекция (negative lookahead), формы (?!expr) и что главным образом значит "не продолжено из-за expr. В случае, если expr совпадите с текстом, настоящая попытка не удается.
Таким образом, использовав ^(?!.*\bvencimiento\b) мы гарантируем себе, что слово vencimiento не будьте во всей линии.

В конце концов, нужно упоминать о том, что я изменил часть даты в твоем выражении, так как [0-1]([0-2]*) только совпади с числами как 00, 11, 112112, и т.д.; но он не совпадает с 05.

Мы заключаем часть даты в скобке, манеры производить группу, и мочь получать только эту специфическую часть с Matcher#group(1).

А именно, мы захватываем дату из-за линии (только одна), каждый раз, когда vencimiento не будьте в той же линии.

Код:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "^(?!.*\\bvencimiento\\b).*\\b([0-3]?\\d[-/][01]?\\d[-/]\\d{4})\\b";
final String texto = "fecha vencimiento 20-12-2017\nfecha 20-12-2017\notra: 12/05/2016";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(texto);

if (matcher.find()) {
    do {
        System.out.println("Fecha: " + matcher.group(1));
    } while (matcher.find());
} else {
    System.out.println("No se encontró ninguna fecha");
}

Результат:

Fecha: 20-12-2017
Fecha: 12/05/2016

Demo:

http://ideone.com/zZxYO3



И как находить дату, всякий раз когда vencimiento не будьте словом, которое предшествует ее (с любым количеством \W в способе)?

В этом случае, мы использовали бы инспекцию назад отрицательная (negative lookbehind). Строительство (?<!expr) Было бы возможно переводить как "настоящее положение не предшествовалось из-за expr".

Вкратце, он был бы:

(?:^\W*|\b(?<!vencimiento)\W+)([0-3]?\d[-/][01]?\d[-/]\d{4}\b)

что, в каждом пределе слова, проверяет, что он не предшествовался из-за vencimiento.

Код:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "(?:^\\W*|\\b(?<!vencimiento)\\W+)([0-3]?\\d[-/][01]?\\d[-/]\\d{4}\\b)";
final String texto = "fecha vencimiento 20-12-2017\nfecha 20-12-2017\notra: 12/05/2016";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(texto);

if (matcher.find()) {
    do {
        System.out.println("Fecha: " + matcher.group(1));
    } while (matcher.find());
} else {
    System.out.println("No se encontró ninguna fecha");
}

Результат:

Fecha: 20-12-2017
Fecha: 12/05/2016

Demo:

http://ideone.com/ccrt55



Альтернативно, чтобы не проверять назад в каждом пределе слова, мы могли бы проверять вперед, немного, что он мог бы быть немного работоспособнее в длинных текстах. Стратегия была бы: тратить положение из-за положения, видеть, ли следующее слово vencimiento и, если он, тратить следующее слово относящейся к владению формы, так что он не смог возвращаться назад.

\G\W*+(?:(?:vencimiento\W+)?+\w+\W+)*?([0-3]?\d[-/][01]?\d[-/]\d{4}\b)

Использовав \G, мы бросаем якорь начало от каждой попытки в начале текста или в конце предыдущего совпадения (если есть более одной даты в тексте).

Код:

final String regex = "\\G\\W*+(?:(?:vencimiento\\W+)?+\\w+\\W+)*?([0-3]?\\d[-/][01]?\\d[-/]\\d{4}\\b)";
final String texto = "fecha vencimiento 20-12-2017\nfecha 20-12-2017\notra: 12/05/2016";

final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(texto);

if (matcher.find()) {
    do {
        System.out.println("Fecha: " + matcher.group(1));
    } while (matcher.find());
} else {
    System.out.println("No se encontró ninguna fecha");
}

Demo:

http://ideone.com/Gahqjl

4
ответ дан 03.12.2019, 17:39
  • 1
    Просто совершенный! Тысячи спасибо! –  16.01.2017, 23:05
  • 2
    Я только что заметил это, он будет приносить мне осложнения. Это много драма validació n, которого esté только раньше из даты? Извини мне беспокойство –  16.01.2017, 23:16
  • 3
    @Genarito - Agregué 2 альтернативы в ответе. Он предотвращал этот тип solució n, так как она менее ясная и немного менее работоспособная (ничто, чтобы беспокоиться). –  16.01.2017, 23:45
  • 4
    Справедливое то, в чем он нуждался! Я тебе благодарен из-за того, что взял на себя труд увеличивать ответ. Привет! –  17.01.2017, 04:07