#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:
Это отличный сайт для построения регулярных выражений от простых до очень сложных. Вы выбираете язык и бум.
Ответ №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 может изменяться.