Jak dopasować „dowolny znak” w wyrażeniu regularnym?

304

Należy dopasować następujące elementy:

AAA123
ABCDEFGH123
XXXX123

Mogę zrobić: ".*123"?

Saobi
źródło
2
Ten link pokazuje podejście, które wydaje się działać -> [^] + Co oznacza „nie dopasowuj żadnych znaków”, podwójny negatyw, który można ponownie przeczytać jako „dopasuj dowolny znak”. Źródło - loune.net/2011/02/…
HockeyJ

Odpowiedzi:

643

Tak, możesz. To powinno działać.

  • . = dowolny znak
  • \. = rzeczywisty znak kropki
  • .?= .{0,1}= dopasuj dowolny znak zero lub jeden raz
  • .*= .{0,}= dopasuj dowolny znak zero lub więcej razy
  • .+= .{1,}= dopasuj dowolny znak jeden lub więcej razy
Delan Azabani
źródło
22
Nie zawsze kropka oznacza dowolny znak. Wyjątek w trybie pojedynczej linii. \ p {wszystko} powinno być
marsjański
Jak dołączyć ukośnik do tej listy postaci?
Wyniki wyszukiwania Wyniki z Internetu Pi
1
@pippilongstocking Backward slash is `\\`
Poutrathor
58

Tak, to zadziała, ale zwróć uwagę, że .nie będzie pasował do nowych wierszy, chyba że podczas kompilacji wyrażenia miniesz flagę DOTALL :

Pattern pattern = Pattern.compile(".*123", Pattern.DOTALL);
Matcher matcher = pattern.matcher(inputStr);
boolean matchFound = matcher.matches();
BlueRaja - Danny Pflughoeft
źródło
11
To bardzo przydatne informacje! Zakładałem, .że pasują do nowych linii. Cieszę się, że przeczytałem twoją odpowiedź, muszę jej użyć!
Ben Kane
Czasami może być konieczne dopasowanie znaków nowej linii w wyrażeniach regularnych Java w kontekstach, w których nie można przekazać Pattern.DOTALL, na przykład podczas wyszukiwania wyrażeń regularnych w wielu wierszach w środowisku Eclipse lub jako użytkownik dowolnej aplikacji Java oferującej wyszukiwanie wyrażeń regularnych. W oparciu o przewodnik regular-expression.info może być konieczne użycie {.,\n,\r,\u2028,\u2029,\u0085}absolutnego dopasowania dowolnego znaku (znaki Unicode to dodatkowe znaki kończące wiersze dodane, niepasujące do .języka Java), ale po prostu {.,\n,\r}działałyby w przypadku większości plików tekstowych.
Theodore Murdock
8
@TheodoreMurdock [\s\S]to popularny sposób dopasowania dowolnej postaci, jeśli nie możesz użyć DOTALL.
mpen
W przypadku, gdy przyjdzie Ci to do głowy, NIE używaj (?:.|\\v)*, ponieważ JDK-6337993 .
Olivier Cailloux
22

Użyj wzorca, .aby dopasować dowolny znak raz, .*aby dopasować dowolny znak zero lub więcej razy, .+aby dopasować dowolny znak jeden lub więcej razy.

thr
źródło
11

Istnieje wiele wyrafinowanych narzędzi do testowania i opracowywania wyrażeń regularnych, ale jeśli chcesz po prostu prostej wiązki testowej w Javie, oto jedno z nich:

    String[] tests = {
        "AAA123",
        "ABCDEFGH123",
        "XXXX123",
        "XYZ123ABC",
        "123123",
        "X123",
        "123",
    };
    for (String test : tests) {
        System.out.println(test + " " +test.matches(".+123"));
    }

Teraz możesz łatwo dodawać nowe przypadki testowe i wypróbowywać nowe wzory. Miłej zabawy podczas odkrywania wyrażenia regularnego.

Zobacz też

środki smarujące wielotlenowe
źródło
1
Głosuj tylko na link regularne-wyrażenia.info. Wspaniała strona do nauki wyrażeń regularnych i odniesienia.
Freiheit
9

Nie, *dopasuje zero lub więcej znaków. Powinieneś użyć +, który zamiast tego pasuje do jednego lub więcej.

To wyrażenie może działać lepiej dla Ciebie: [A-Z]+123

Huusom
źródło
1
Głosuj tutaj. OP nie określił, ale poprawne wydaje się dodanie, że wzorzec będzie pasował do dowolnego znaku, w tym np. ### 123, 123123,% $ # 123, którego OP może nie chcieć. Klasa znaków, której używa @Huusom, sprawi, że wszystkie OP będą używać tylko wielkich liter, które mogły być zamierzone.
techdude
9

Najczęstszym sposobem, w jaki widziałem to kodować, jest klasa znaków, której członkowie tworzą partycję zestawu wszystkich możliwych znaków.

Zazwyczaj ludzie piszą, że jako [\s\S](spacji lub braku spacji), choć [\w\W], [\d\D]itp by wszystkie prace.

Jamie Davis
źródło
2
Dla odniesienia, z regular-expressions.info/dot.html : „JavaScript i VBScript nie mają opcji dopasowania kropki do znaków podziału linii. W tych językach można użyć klasy znaków, takiej jak [\ s \ S] aby dopasować dowolny znak. Znak ten pasuje do znaku, który jest albo znakiem spacji (w tym znakami podziału wiersza), albo znakiem, który nie jest znakiem spacji. Ponieważ wszystkie znaki są spacjami lub spacjami, ta klasa znaków pasuje do dowolnego znaku . ”
Dziekan lub
7

.*i .+są dla dowolnych znaków z wyjątkiem nowych linii.

Podwójna ucieczka

Na wszelki wypadek, gdybyś chciał dołączyć nowe wiersze, poniższe wyrażenia mogą również działać w tych językach, w których wymagane jest podwójne znaki zmiany znaczenia, takich jak Java lub C ++:

[\\s\\S]*
[\\d\\D]*
[\\w\\W]*

zero lub więcej razy, lub

[\\s\\S]+
[\\d\\D]+
[\\w\\W]+

jeden lub więcej razy.

Pojedynczy ucieczka:

Podwójne zmiany znaczenia nie jest wymagane w przypadku niektórych języków, takich jak, C #, PHP, Ruby, PERL, Python, JavaScript:

[\s\S]*
[\d\D]*
[\w\W]*
[\s\S]+
[\d\D]+
[\w\W]+

Test

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


public class RegularExpression{

    public static void main(String[] args){

        final String regex_1 = "[\\s\\S]*";
        final String regex_2 = "[\\d\\D]*";
        final String regex_3 = "[\\w\\W]*";
        final String string = "AAA123\n\t"
             + "ABCDEFGH123\n\t"
             + "XXXX123\n\t";

        final Pattern pattern_1 = Pattern.compile(regex_1);
        final Pattern pattern_2 = Pattern.compile(regex_2);
        final Pattern pattern_3 = Pattern.compile(regex_3);

        final Matcher matcher_1 = pattern_1.matcher(string);
        final Matcher matcher_2 = pattern_2.matcher(string);
        final Matcher matcher_3 = pattern_3.matcher(string);

        if (matcher_1.find()) {
            System.out.println("Full Match for Expression 1: " + matcher_1.group(0));
        }

        if (matcher_2.find()) {
            System.out.println("Full Match for Expression 2: " + matcher_2.group(0));
        }
        if (matcher_3.find()) {
            System.out.println("Full Match for Expression 3: " + matcher_3.group(0));
        }
    }
}

Wynik

Full Match for Expression 1: AAA123
    ABCDEFGH123
    XXXX123

Full Match for Expression 2: AAA123
    ABCDEFGH123
    XXXX123

Full Match for Expression 3: AAA123
    ABCDEFGH123
    XXXX123

Jeśli chcesz poznać wyrażenie, wyjaśniono je w prawym górnym panelu strony regex101.com . Jeśli chcesz, możesz również obejrzeć w tym linku , jak będzie pasował do niektórych przykładowych danych wejściowych.


Obwód RegEx

jex.im wizualizuje wyrażenia regularne:

wprowadź opis zdjęcia tutaj

Emma
źródło
1
Czy nie ma tu już odpowiedzi? stackoverflow.com/a/55149095/5424988
Czwarty ptak
lubię (\W|\w)*zamiast podwójnej ucieczki
Sudip Bhattarai
1
Naprawdę pomocne wyjaśnienie
Nagibaba
5

Konkretne rozwiązanie przykładowego problemu: -

Spróbuj [A-Z]*123$będzie pasował 123, AAA123, ASDFRRF123. Jeśli potrzebujesz przynajmniej postaci przed 123użyciem [A-Z]+123$.

Ogólne rozwiązanie pytania (Jak dopasować „dowolny znak” w wyrażeniu regularnym):

  1. Jeśli szukasz czegoś, w tym białych znaków, możesz spróbować [\w|\W]{min_char_to_match,}.
  2. Jeśli próbujesz dopasować cokolwiek oprócz białych znaków, możesz spróbować [\S]{min_char_to_match,}.
Akash Kumar Seth
źródło
2

[^]powinien pasować do dowolnego znaku, w tym nowego wiersza. [^CHARS] pasuje do wszystkich znaków oprócz tych w CHARS . Jeśli CHARS jest pusty, pasuje do wszystkich znaków.

Przykład JavaScript:

/a[^]*Z/.test("abcxyz \0\r\n\t012789ABCXYZ") // Returns ‘true’.
Anonimowy
źródło
Czy masz coś przeciwko dodaniu kodu, aby poinformować nas o swoich próbach?
Jennis Vaishnav
1

Wypróbuj wyrażenie regularne .{3,}. Spowoduje to dopasowanie wszystkich znaków oprócz nowej linii.

Ravi Shekhar
źródło
-4

Pracuję nad tym Nie zawsze kropka oznacza dowolny znak. Wyjątek w trybie pojedynczej linii. \p{all}Powinien być

String value = "|°¬<>!\"#$%&/()=?'\\¡¿/*-+_@[]^^{}";
String expression = "[a-zA-Z0-9\\p{all}]{0,50}";
if(value.matches(expression)){
    System.out.println("true");
} else {
    System.out.println("false");
}
Abrahan Gonzalez
źródło