Разбор строки на Java

#java #parsing

#java #синтаксический анализ

Вопрос:

У меня есть строки, отформатированные аналогично приведенному ниже в программе Java. Мне нужно вывести число.

 Host is up (0.0020s latency).
  

Мне нужно число между символами ‘(‘ и ‘s’. Например, в этом примере мне понадобилось бы 0.0020.

Ответ №1:

Если вы уверены, что это всегда будет первое число, вы можете использовать обычное выражение d .d (но обратите внимание, что обратные косые черты должны быть экранированы в строковых литералах Java).

Попробуйте этот код:

 String input = "Host is up (0.0020s latency).";
Pattern pattern = Pattern.compile("\d \.\d ");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
    System.out.println(matcher.group());
}
  

Посмотрите, как это работает онлайн: ideone

Вы также можете включить некоторые из окружающих символов в регулярное выражение, чтобы уменьшить риск сопоставления неправильного числа. Чтобы выполнить именно то, что вы просили в вопросе (т. Е. сопоставление между ( и s ), используйте это регулярное выражение:

 ((d .d )s
  

Посмотрите, как это работает онлайн: ideone

Ответ №2:

Звучит как пример регулярных выражений.

Вы захотите сопоставить десятичную цифру, а затем проанализировать это соответствие:

 Float matchedValue;
Pattern pattern = Pattern.compile("\d*\.\d ");
Matcher matcher = pattern.matcher(yourString);
boolean isfound = matcher.find();

if (isfound) {
    matchedValue = Float.valueOf(matcher.group(0));
}
  

Комментарии:

1. Я сделал небольшое регулярное выражение в Perl. Но я не знаю, как это сделать в Java.

2. Я обновил свой, однако имейте в виду, что у float есть некоторые проблемы с точностью, поэтому вы, вероятно, захотите использовать BigDecimal вместо этого, как показано в примере Джона Скита, если требуется точность. Кроме того, мой не защищен от нескольких совпадений и т.д.

3. Если число не найдено, ваш шаблон будет соответствовать пустой строке (или одному '.' ), что Float.valueOf(...) приведет к возникновению исключения.

Ответ №3:

Это зависит от того, насколько «похоже» вы имеете в виду. Потенциально вы могли бы использовать регулярное выражение:

 import java.math.BigDecimal;
import java.util.regex.*;

public class Test {
    public static void main(String args[]) throws Exception {
        Pattern pattern = Pattern.compile("[^(]*\(([0-9]*\.[0-9]*)s");        
        String text = "Host is up (0.0020s latency).";

        Matcher match = pattern.matcher(text);
        if (match.lookingAt())
        {
            String group = match.group(1);
            System.out.println("Before parsing: "   group);
            BigDecimal value = new BigDecimal(group);
            System.out.println("Parsed: "   value);
        }
        else
        {
            System.out.println("No match");
        }
    }
}
  

Насколько конкретным вы хотите сделать свой шаблон, конечно, зависит от вас. При этом проверяются только цифры, точка, затем цифры после открывающей скобки и перед s . Возможно, вам потребуется уточнить ее, чтобы сделать точку необязательной и т.д.

Ответ №4:

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

http://txt2re.com/

Ответ №5:

Вот способ без регулярных выражений

     String str = "Host is up (0.0020s latency).";
    str = str.substring(str.indexOf('(') 1, str.indexOf("s l"));
    System.out.println(str);
  

Комментарии:

1. Это предполагает, что «похожие» строки будут в этом формате.

Ответ №6:

Конечно, использование регулярных выражений в этом случае является лучшим решением, но во многих простых случаях вы также можете использовать что-то вроде :

String value = myString.subString(myString.indexOf("("), myString.lastIndexOf("s")) двойное числовое значение = Double.parseDouble(значение);

Это не рекомендуется, потому что текст в myString может изменяться.