Używanie wyrażeń regularnych do wyodrębniania wartości w Javie

Mam kilka ciągów w postaci szorstkiej:

[some text] [some number] [some more text]

Chcę wyodrębnić tekst z [pewnej liczby] za pomocą klas Java Regex.

Wiem z grubsza, jakiego wyrażenia regularnego chcę użyć (chociaż wszystkie sugestie są mile widziane). To, co mnie naprawdę interesuje, to wywołania Javy, aby wziąć łańcuch regex i użyć go na danych źródłowych do wytworzenia wartości [pewnej liczby].

EDIT: dodam, że interesuje mnie tylko jedna [jakaś liczba] (w zasadzie pierwsza instancja). Ciągi źródłowe są krótkie i nie będę szukał wielu wystąpień [pewnej liczby].

 139
Author: Craig Walker, 2008-10-26

13 answers

Pełny przykład:

private static final Pattern p = Pattern.compile("^([a-zA-Z]+)([0-9]+)(.*)");
public static void main(String[] args) {
    // create matcher for pattern p and given string
    Matcher m = p.matcher("Testing123Testing");

    // if an occurrence if a pattern was found in a given string...
    if (m.find()) {
        // ...then you can use group() methods.
        System.out.println(m.group(0)); // whole matched expression
        System.out.println(m.group(1)); // first expression from round brackets (Testing)
        System.out.println(m.group(2)); // second one (123)
        System.out.println(m.group(3)); // third one (Testing)
    }
}

Ponieważ szukasz pierwszej liczby, możesz użyć wyrażenia regularnego:

^\D+(\d+).*

I m.group(1) zwrócą Ci pierwszą liczbę. Zauważ, że podpisane liczby mogą zawierać znak minus:

^\D+(-?\d+).*
 266
Author: Allain Lalonde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-28 23:29:40

Allain zasadniczo ma kod java, więc możesz go użyć. Jednak jego wyrażenie pasuje tylko do , Jeśli twoje liczby są poprzedzone tylko strumieniem znaków wyrazowych.

"(\\d+)"

Powinien być w stanie znaleźć pierwszy ciąg cyfr. Nie musisz określać, co jest przed nim, jeśli jesteś pewien, że będzie to pierwszy ciąg cyfr. Podobnie, nie ma sensu określać, co jest po nim, chyba że chcesz tego. Jeśli chcesz tylko numer i jesteś pewien, że będzie to pierwszy ciąg jednej lub więcej cyfr to wszystko, czego potrzebujesz.

Jeśli spodziewasz się, że zostanie przesunięta przez spacje, będzie jeszcze bardziej wyraźne określenie

"\\s+(\\d+)\\s+"
Może być lepiej.

Jeśli potrzebujesz wszystkich trzech części, to wystarczy:

"(\\D+)(\\d+)(.*)"

Edytuj wyrażenia podane przez Allaina i Jacka sugerują, że musisz określić podzbiór niecyfrów, aby uchwycić cyfry . Jeśli powiesz silnikowi regex, którego szukasz \d, to ignoruj wszystko przed cyframi. Jeśli wyrażenie J lub A pasuje do twojego wzorca, to całe dopasowanie równa się łańcuch wejściowy. I nie ma powodu, by to określać. Prawdopodobnie spowalnia czyste dopasowanie, Jeśli nie jest całkowicie ignorowane.

 33
Author: Axeman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 13:36:17
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Regex1 {
    public static void main(String[]args) {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("hello1234goodboy789very2345");
        while(m.find()) {
            System.out.println(m.group());
        }
    }
}

Wyjście:

1234
789
2345
 32
Author: javaMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-29 17:52:13

Oprócz Pattern , Klasa Java String posiada również kilka metod, które mogą pracować z wyrażeniami regularnymi, w Twoim przypadku kod będzie:

"ab123abc".replaceFirst("\\D*(\\d*).*", "$1")

Gdzie \\D jest znakiem niecyfrowym.

 11
Author: Vitalii Fedorenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-20 00:08:44

W Javie 1.4 i nowszych:

String input = "...";
Matcher matcher = Pattern.compile("[^0-9]+([0-9]+)[^0-9]+").matcher(input);
if (matcher.find()) {
    String someNumberStr = matcher.group(1);
    // if you need this to be an int:
    int someNumberInt = Integer.parseInt(someNumberStr);
}
 9
Author: Jack Leow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-25 23:56:16

Ta funkcja zbiera wszystkie pasujące sekwencje z string. W tym przykładzie pobiera wszystkie adresy e-mail z string.

static final String EMAIL_PATTERN = "[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
        + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})";

public List<String> getAllEmails(String message) {      
    List<String> result = null;
    Matcher matcher = Pattern.compile(EMAIL_PATTERN).matcher(message);

    if (matcher.find()) {
        result = new ArrayList<String>();
        result.add(matcher.group());

        while (matcher.find()) {
            result.add(matcher.group());
        }
    }

    return result;
}

Dla message = "[email protected], <[email protected]>>>> [email protected]" utworzy listę 3 elementów.

 6
Author: LukTar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 12:19:52

Spróbuj zrobić coś takiego:

Pattern p = Pattern.compile("^.+(\\d+).+");
Matcher m = p.matcher("Testing123Testing");

if (m.find()) {
    System.out.println(m.group(1));
}
 2
Author: Tint Naing Win,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-17 15:30:29

Spójrz możesz to zrobić używając StringTokenizer

String str = "as:"+123+"as:"+234+"as:"+345;
StringTokenizer st = new StringTokenizer(str,"as:");

while(st.hasMoreTokens())
{
  String k = st.nextToken();    // you will get first numeric data i.e 123
  int kk = Integer.parseInt(k);
  System.out.println("k string token in integer        " + kk);

  String k1 = st.nextToken();   //  you will get second numeric data i.e 234
  int kk1 = Integer.parseInt(k1);
  System.out.println("new string k1 token in integer   :" + kk1);

  String k2 = st.nextToken();   //  you will get third numeric data i.e 345
  int kk2 = Integer.parseInt(k2);
  System.out.println("k2 string token is in integer   : " + kk2);
}

Ponieważ bierzemy te dane liczbowe do trzech różnych zmiennych, możemy użyć tych danych w dowolnym miejscu kodu (do dalszego wykorzystania)

 1
Author: shounak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-24 04:16:17

Proste Rozwiązanie

// Regexplanation:
// ^       beginning of line
// \\D+    1+ non-digit characters
// (\\d+)  1+ digit characters in a capture group
// .*      0+ any character
String regexStr = "^\\D+(\\d+).*";

// Compile the regex String into a Pattern
Pattern p = Pattern.compile(regexStr);

// Create a matcher with the input String
Matcher m = p.matcher(inputStr);

// If we find a match
if (m.find()) {
    // Get the String from the first capture group
    String someDigits = m.group(1);
    // ...do something with someDigits
}

Roztwór w klasie Util

public class MyUtil {
    private static Pattern pattern = Pattern.compile("^\\D+(\\d+).*");
    private static Matcher matcher = pattern.matcher("");

    // Assumptions: inputStr is a non-null String
    public static String extractFirstNumber(String inputStr){
        // Reset the matcher with a new input String
        matcher.reset(inputStr);

        // Check if there's a match
        if(matcher.find()){
            // Return the number (in the first capture group)
            return matcher.group(1);
        }else{
            // Return some default value, if there is no match
            return null;
        }
    }
}

...

// Use the util function and print out the result
String firstNum = MyUtil.extractFirstNumber("Testing4234Things");
System.out.println(firstNum);
 1
Author: NoBrainer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-23 23:00:18

A może [^\\d]*([0-9]+[\\s]*[.,]{0,1}[\\s]*[0-9]*).* myślę, że zajmie się liczbami z częścią ułamkową. Włączyłem białe spacje i włączyłem , jako możliwy separator. Staram się wydobyć liczby z Ciągu, w tym pływaków i biorąc pod uwagę, że użytkownik może popełnić błąd i zawierać białe spacje podczas wpisywania numeru.

 0
Author: arturo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-14 00:38:27
Pattern p = Pattern.compile("(\\D+)(\\d+)(.*)");
Matcher m = p.matcher("this is your number:1234 thank you");
if (m.find()) {
    String someNumberStr = m.group(2);
    int someNumberInt = Integer.parseInt(someNumberStr);
}
 0
Author: User User,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-22 09:47:44

Czasami można użyć simple .metoda split ("REGEXP") dostępna w Javie.lang.Sznurek. Na przykład:

String input = "first,second,third";

//To retrieve 'first' 
input.split(",")[0] 
//second
input.split(",")[1]
//third
input.split(",")[2]
 -1
Author: user1722707,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-11 10:23:51

Jeśli czytasz z pliku, to może Ci to pomóc

              try{
             InputStream inputStream = (InputStream) mnpMainBean.getUploadedBulk().getInputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
             String line;
             //Ref:03
             while ((line = br.readLine()) != null) {
                if (line.matches("[A-Z],\\d,(\\d*,){2}(\\s*\\d*\\|\\d*:)+")) {
                     String[] splitRecord = line.split(",");
                     //do something
                 }
                 else{
                     br.close();
                     //error
                     return;
                 }
             }
                br.close();

             }
         }
         catch (IOException  ioExpception){
             logger.logDebug("Exception " + ioExpception.getStackTrace());
         }
 -1
Author: seeker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-11 10:43:52