#java #regex #extract #matcher
#java #регулярное выражение #извлечение #сопоставитель
Вопрос:
У меня очень длинный текст, и я извлекаю некоторые конкретные значения, за которыми следуют некоторые конкретные слова. Вот пример моего длинного текста:
.........
FPS(FramesPerSecond)[ValMin: 29.0000, ValMax: 35.000]
.........
TotalFrames[ValMin: 100000, ValMax:200000]
.........
MemoryUsage(In MB)[ValMin:190000MB, ValMax:360000MB]
.........
вот мой код:
File file = filePath.toFile();
JSONObject jsonObject = new JSONObject();
String FPSMin="";
String FPSMax="";
String TotalFramesMin="";
String TotalFramesMax="";
String MemUsageMin="";
String MemUsageMax="";
String log = "my//log//file";
final Matcher matcher = Pattern.compile("FPS/(FramesPerSecond/)/[ValMin:");
if(matcher.find()){
FPSMin= matcher.end().trim();
}
Но я не могу заставить это работать. Где я ошибаюсь? По сути, мне нужно выбрать для каждой строки соответствующие значения (max и min), исходящие из этого длинного текста, и сохранить их в переменных. Нравится
FPSMin = 29.0000
FPSMax = 35.0000
FramesMin = 100000
Etc
Спасибо
РЕДАКТИРОВАТЬ: я попробовал следующий код (в тестовом примере), чтобы посмотреть, может ли решение работать, но у меня возникают проблемы, потому что я не могу напечатать ничего, кроме объекта. Вот код:
@Test
public void whenReadLargeFileJava7_thenCorrect()
throws IOException, URISyntaxException {
Scanner txtScan = new Scanner("path//to//file//test.txt");
String[] FPSMin= new String[0];
String FPSMax= "";
//Read File Line By Line
while (txtScan.hasNextLine()) {
// Print the content on the console
String str = txtScan.nextLine();
Pattern FPSMin= Pattern.compile("^FPS\(FramesPerSecond\)\[ValMin:");
Matcher matcher = FPSMin.matcher(str);
if(matcher.find()){
String MinMaxFPS= str.substring(matcher.end(), str.length()-1);
String[] splitted = MinMaxFPS.split(",");
FPSMin= splitted[0].split(": ");
FPSMax = splitted[1];
}
System.out.println(FPSMin);
System.out.println(FPSMax);
}
Комментарии:
1. Не уверен, чего вы хотите достичь, но ваш код даже не компилируется. Я часто задаюсь вопросом, почему люди борются с регулярными выражениями вместо того, чтобы сначала попытаться использовать простой способ (подстроку).
2. Мне нужно выбрать значения из текстового журнала и сохранить их в переменные с помощью регулярных выражений. Например, минимальное значение FPS, максимальное значение FPS и т. Д
3. @Smutje как я могу это сделать, используя substring ? Это один файл журнала, но очень длинный
4. Я бы предложил упростить ваш пример, удалив каждую ненужную строку кода (например, файловую часть), чтобы сузить причины, по которым регулярное выражение не будет работать. Кроме того, это помогает другим пользователям помочь вам, если они могут скомпилировать ваш код на своих машинах без дополнительных затрат.
Ответ №1:
Возможно, ваш шаблон должен быть таким ^FPS\(FramesPerSecond\)\[ValMin:
. Я пробовал, и у меня это работает.
String line = "FPS(FramesPerSecond)[ValMin: 29.0000, ValMax: 35.000]";
Pattern pattern = Pattern.compile("^FPS\(FramesPerSecond\)\[ValMin:");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
System.out.println(line.substring(matcher.end(), line.length()-1));
}
}
Таким образом, вы получаете смещение строки, из которой хотите извлечь данные, и, используя функцию substring, вы можете получить все символы, начиная со смещения до размера строки-1 (потому что вы не хотите также получать символ ])
Комментарии:
1. Не могли бы вы показать мне свой код? У меня это не работает, и в нем говорится, что мне нужно изменить сопоставитель с шаблоном
2. @thranduil90 это потому
Pattern#compile
, что возвращает aPattern
, а не aMatcher
,3. Это идеально, спасибо! Но как я могу сохранить минимальные и максимальные значения в разных переменных?
4. @Smutje Спасибо, я исправил проблему с шаблоном и сопоставителем. Теперь мне просто нужно разобраться, как выбрать Min и Max и назначить их разным переменным
5. Одним из способов может быть использование функции split(). После получения результата ValMin: 29.000, ValMax: 35.000 используя приведенный выше код, который я упомянул, вы могли бы сделать
String[] splitted = result.split(",")
, где result — это строка для хранения результата приведенного выше кода, и при разделении [0] у вас будет ValMin: 29.000, а при разделении [1] у вас будет ValMax: 35.000. Тогда таким же образом, как вы могли бы сделатьString[] minVal = splitted[1].split(": ")
, и на minVal [1] вы получите 29.000. Аналогично, сделайте то же самое для ValMax
Ответ №2:
Следующее регулярное выражение будет соответствовать и фиксировать имя, минимальное и максимальное:
Pattern.compile("(.*)\[. :\s*(\d (?:\.\d )?)[A-Z]*,. :\s*(\d (?:\.\d )?)[A-Z]*\]");
Использование (извлечение захваченных групп):
String input = (".........n"
"FPS(FramesPerSecond)[ValMin: 29.0000, ValMax: 35.000]n"
".........n"
"TotalFrames[ValMin: 100000, ValMax:200000]n"
".........n"
"MemoryUsage(In MB)[ValMin:190000MB, ValMax:360000MB]n"
".........");
for (String s : input.split("n")) {
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
System.out.println(matcher.group(1) ", " matcher.group(2) ", " matcher.group(3));
}
}
Вывод:
FPS (FramesPerSecond), 29.0000, 35.000
totalFrames, 100000, 200000
MemoryUsage (в МБ), 190000, 360000
Комментарии:
1. Спасибо! Но точки были просто примером, там много бесполезного текста. Как мне изменить шаблон, чтобы он включал только фреймы, totalFrames и MemoryUsage?
2. Вместо того, чтобы сопоставлять что-либо перед первой квадратной скобкой
(.*)
, тогда вы будете сопоставлять только(FPS(FramesPerSecond)|TotalFrames|MemoryUsage(In MB))
. Или вы используете исходный шаблон и фильтруете по первой группе (если имя находится в наборе из этих трех имен).