Я пытаюсь создать регулярное выражение для возврата исходного значения, а затем всех пар значений ключа.
Текст
abcd{123}hello world{456}asd * ~ . , 1243214 aadasd{678}asd aaasddd
Ожидаемый результат
HEADER -> abcd
123 -> hello world
456 -> asd * ~ . , 1243214 aadasd
678 -> asd aaasddd
Заранее спасибо...
Я пробовал использовать регулярное выражение ниже, но оно не дает правильных результатов
(?:{\d{4}})([\w]+[\S]*[.,]*[\s]+)
Вы можете использовать:
([^\\{\\r\\n]+)?\\{\\s*(\\d+)\\s*\\}([^\\{\\r\\n]+)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Solution {
public static void main(String[] args) {
String s = "abcd{123}hello world{456}asd * ~ . , 1243214 aadasd{678}asd aaasddd";
String p = "([^\\{\\r\\n]+)?\\{\\s*(\\d+)\\s*\\}([^\\{\\r\\n]+)";
Pattern pattern = Pattern.compile(p);
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
String header = matcher.group(1);
String key = matcher.group(2);
String value = matcher.group(3);
if (header != null) {
System.out.println("HEADER -> " + header);
}
System.out.println(key + " -> " + value.trim());
}
}
}
HEADER -> abcd
123 -> hello world
456 -> asd * ~ . , 1243214 aadasd
678 -> asd aaasddd
([^{\r\n]+)?
: захватить группу 1 для ЗАГОЛОВКА (необязательно ?
).({\d+})
: захватите группу 2 по цифрам.([^{\r\n]+)
: захватите группу 3 для значений.Спасибо за быстрый ответ. Это работает отлично, за исключением части ЗАГОЛОВКА. Заголовок также может содержать любые символы. Например. .....01.FTI0350 .FTR811XFT811 {123}привет, мир Пожалуйста, измените свое регулярное выражение, чтобы отразить это
@wasankawickramasinghe Попробуйте ([^\{\r\n]+)?\{\s*(\d+)\s*\}([^\{\r\n]+)
?
Если заголовок и все значения должны содержать хотя бы один символ без пробелов и предполагается, что единственные фигурные, которые вы сопоставляете, окружены цифрами:
(?:^\h*+(?!.*}\h*(?:\{|$))([^{}\r\n]+)|\G(?!^))\{(\d+)}([^{}\r\n]+)
Узор соответствует:
(?:
Группа без захвата
^
Начало строки\h*+
Сопоставьте необязательные ведущие горизонтальные пробельные символы с притяжательным квантором.(?!.*}\h*(?:\{|$))
Утвердить, что справа после }
есть не только горизонтальные пробельные символы до следующего {
или конца строки.([^{}\r\n]+)
Захватить группу 1, сопоставить 1+ символов, отличных от перечисленных в классе отрицательных символов.|
Или\G(?!^)
Укажите позицию в конце предыдущего совпадения, а не в начале строки.)
Закройте группу без захвата\{(\d+)}
Захватите 1+ цифр между фигурными скобками в группе 2([^{}\r\n]+)
Захватить группу 3, сопоставить 1+ символов, кроме {
и }
Посмотрите демонстрацию регулярных выражений и демонстрацию Java
Пример на Java:
String regex = "(?:^\\h*+(?!.*\\}\\h*(?:\\{|$))([^\\{\\}\\r\\n]+)|\\G(?!^))\\{(\\d+)\\}([^\\{\\}\\r\\n]+)";
String string = "abcd{123}hello world{456}asd * ~ . , 1243214 aadasd{678}asd aaasddd";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher m = pattern.matcher(string);
while (m.find()) {
if (m.group(1) != null) {
System.out.printf("HEADER -> %s%n", m.group(1));
}
System.out.printf("%s -> %s%n", m.group(2), m.group(3));
}
Выход
HEADER -> abcd
123 -> hello world
456 -> asd * ~ . , 1243214 aadasd
678 -> asd aaasddd
Regex можно использовать для выполнения удивительных преобразований текста, о чем свидетельствуют другие ответы (и принятые). Однако, если вы работаете в команде, подумайте о том, чтобы следующий человек отредактировал ваш код. Некоторые могут быть менее рады применять обновления к:
([^\\{\\r\\n]+)?\\{\\s*(\\d+)\\s*\\}([^\\{\\r\\n]+)
(?:^\h*+(?!.*}\h*(?:\{|$))([^{}\r\n]+)|\G(?!^))\{(\d+)}([^{}\r\n]+)
Вы показали очень простой формат, очень похожий на CSV, но с чередующимися разделителями:
String line = "abcd{123}hello world{456}asd * ~ . , 1243214 aadasd{678}asd aaasddd";
Есть несколько более простых способов извлечь текст — даже с помощью String.indexOf
. Вот несколько предложений, которые вытягивают ваши поля в одну/две строки:
String[] fields = line.split("[\\{\\}]");
Пример доступа:
System.out.println("HEADER -> "+fields[0]);
for (int i = 1; i < fields.length; i+=2) {
System.out.println(fields[i]+" -> "+fields[i+1]);
}
Альтернатива:
String[] fields = line.split("\\{");
System.out.println("HEADER -> "+fields[0]);
for (int i = 1; i < fields.length; i++) {
String[] kv = fields[i].split("\\}");
System.out.println(kv[0]+" -> "+kv[1]);
}
Выход
HEADER -> abcd
123 -> hello world
456 -> asd * ~ . , 1243214 aadasd
678 -> asd aaasddd
Очевидно, что эти предложения могут не касаться пунктуации и проверки случаев, но их легче поддерживать.
немного сбивает с толку: в примере у вас трехзначные числа, но в регулярном выражении вы используете
\d{4}
, то есть 4-значные?!? И просто пример - не лучшее описание...