/ / Jak ustalić, gdzie nie można dopasować wyrażenia regularnego za pomocą interfejsów API Java - java, regex

Jak ustalić, gdzie nie można dopasować wyrażenia regularnego za pomocą interfejsów API Java - java, regex

Mam testy, w których sprawdzam poprawność wyniku za pomocą wyrażenia regularnego. Gdy zawiedzie, informuje, że wyjście X nie pasuje do wyrażenia regularnego Y.

Chciałbym dodać wskazanie, gdzie w łańcuchu nie powiodło się dopasowanie. Na przykład. co jest najdalsze, że matcher znalazł się w sznurku przed cofnięciem. Matcher.hitEnd() to jeden przypadek tego, czego szukam, ale chcę czegoś bardziej ogólnego.

Czy to się da zrobić?

Odpowiedzi:

6 dla odpowiedzi № 1

Jeśli mecz się nie powiedzie Match.hitEnd() informuje, czy może mieć dłuższy ciągdopasowane. Ponadto można określić region w sekwencji wejściowej, który zostanie przeszukany, aby znaleźć dopasowanie. Jeśli więc masz ciąg, którego nie można dopasować, możesz przetestować jego prefiksy, aby zobaczyć, gdzie zawodzi dopasowanie:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LastMatch {
private static int indexOfLastMatch(Pattern pattern, String input) {
Matcher matcher = pattern.matcher(input);
for (int i = input.length(); i > 0; --i) {
Matcher region = matcher.region(0, i);
if (region.matches() || region.hitEnd()) {
return i;
}
}

return 0;
}

public static void main(String[] args) {
Pattern pattern = Pattern.compile("[A-Z]+[0-9]+[a-z]+");
String[] samples = {
"*ABC",
"A1b*",
"AB12uv",
"AB12uv*",
"ABCDabc",
"ABC123X"
};

for (String sample : samples) {
int lastMatch = indexOfLastMatch(pattern, sample);
System.out.println(sample + ": last match at " + lastMatch);
}
}
}

Rezultatem tej klasy jest:

*ABC: last match at 0
A1b*: last match at 3
AB12uv: last match at 6
AB12uv*: last match at 6
ABCDabc: last match at 4
ABC123X: last match at 6

3 dla odpowiedzi № 2

Możesz wziąć łańcuch i iterować po nim, usuwając kolejny znak z końca każdej iteracji, a następnie sprawdzając hitEnd():

int farthestPoint(Pattern pattern, String input) {
for (int i = input.length() - 1; i > 0; i--) {
Matcher matcher = pattern.matcher(input.substring(0, i));
if (!matcher.matches() && matcher.hitEnd()) {
return i;
}
}
return 0;
}

1 dla odpowiedzi nr 3

Możesz użyć pary replaceAll() wzywa do wskazania pozytywnych i negatywnychdopasowania ciągu wejściowego. Powiedzmy na przykład, że chcesz sprawdzić poprawność ciągu szesnastkowego, a poniżej wskaże poprawne i nieprawidłowe znaki ciągu wejściowego.

String regex = "[0-9A-F]"
String input = "J900ZZAAFZ99X"
Pattern p = Pattern.compile(regex)
Matcher m = p.matcher(input)
String mask = m.replaceAll("+").replaceAll("[^+]", "-")
System.out.println(input)
System.out.println(mask)

Spowoduje to wydrukowanie poniższego, za pomocą + pod poprawnymi znakami i a - pod błędnymi znakami.

J900ZZAAFZ99X
-+++--+++-++-

0 dla odpowiedzi nr 4

Jeśli chcesz to zrobić poza kodem, używam rubularny przetestować wyrażenia wyrażenia regularnego przed wklejeniem ich do kodu.