Использование регулярных выражений для извлечения значения в Java - PullRequest
152 голосов
/ 26 октября 2008

У меня есть несколько строк в грубой форме:

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

Я хочу извлечь текст из [некоторого числа], используя классы Java Regex.

Я примерно знаю, какое регулярное выражение я хочу использовать (хотя все предложения приветствуются). Что меня действительно интересует, так это вызовы Java для получения строки регулярного выражения и ее использования в исходных данных для получения значения [some number].

РЕДАКТИРОВАТЬ: Я должен добавить, что меня интересует только один [некоторый номер] (в основном, первый экземпляр). Исходные строки короткие, и я не собираюсь искать несколько вхождений [некоторого числа].

Ответы [ 13 ]

291 голосов
/ 26 октября 2008

Полный пример:

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)
    }
}

Поскольку вы ищете первый номер, вы можете использовать такое регулярное выражение:

^\D+(\d+).*

и m.group(1) вернут вам первый номер. Обратите внимание, что числа со знаком могут содержать знак минус:

^\D+(-?\d+).*
36 голосов
/ 14 ноября 2011
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());
        }
    }
}

Выход:

1234
789
2345
33 голосов
/ 26 октября 2008

Аллен в основном имеет Java-код, так что вы можете использовать его. Однако его выражение соответствует , если вашим числам предшествует только поток слов.

"(\\d+)"

должен быть в состоянии найти первую строку цифр. Вам не нужно указывать, что перед ним, если вы уверены, что это будет первая строка цифр. Кроме того, нет смысла указывать, что после этого, если вы этого не хотите. Если вам просто нужен номер, и вы уверены, что это будет первая строка из одной или нескольких цифр, то это все, что вам нужно.

Если вы ожидаете, что он будет смещен пробелами, это сделает его еще более отчетливым для указания

"\\s+(\\d+)\\s+"

может быть лучше.

Если вам нужны все три части, это будет делать:

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

РЕДАКТИРОВАТЬ Выражения, данные Алленом и Джеком, предполагают, что вам нужно указать некоторое подмножество нецифровых чисел для захвата цифр . Если вы скажете движку регулярных выражений, что ищете \d, то он будет игнорировать все до цифр. Если выражение J или A соответствует вашему шаблону, то полное совпадение равно входной строке . И нет никаких оснований указывать это. Это, вероятно, замедляет чистое совпадение, если не полностью игнорируется.

11 голосов
/ 20 февраля 2012

В дополнение к Pattern класс Java String также имеет несколько методов, которые могут работать с регулярными выражениями, в вашем случае код будет:

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

, где \\D - нецифровый символ.

10 голосов
/ 26 октября 2008

В Java 1.4 и выше:

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);
}
6 голосов
/ 17 декабря 2012

Эта функция собирает все подходящие последовательности из строки. В этом примере он берет все адреса электронной почты из строки.

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;
}

Для message = "adf@gmail.com, <another@osiem.osiem>>>> lalala@aaa.pl" будет создан список из 3 элементов.

3 голосов
/ 05 апреля 2011

Попробуйте сделать что-то вроде этого:

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

if (m.find()) {
    System.out.println(m.group(1));
}
2 голосов
/ 24 июня 2015

Простое решение

// 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
}

Решение в классе 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 голос
/ 24 мая 2012

Смотри, ты можешь сделать это, используя 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);
}

Поскольку мы берем эти числовые данные в трех различных переменных, мы можем использовать эти данные в любом месте кода (для дальнейшего использования)

0 голосов
/ 22 августа 2016
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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...