Если вербализировать ту идею которую подал @Stanislav Volodarskiy то получится примерно такой код возвращающий в данном случае массив массивов где подмасив состоит из ключевого слова и значения:
const strings = [
"abc part is created (message 42)",
"abc (message 42) part.id=24",
"abc order.id=123, 5 (message 42) 5 part.id=321 5",
"[message 42] Part with id 34 added to Order 22",
"abc Order (id=3, part.id=56) is generated \"message 42\"",
"Can't create order, becasue part 4 not found",
"Order 5 cannot be created because a part is missing"]
for (const str of strings){
const temp = []
for (const spart of str.matchAll(/part|message|order|[0-9]+/gi)){
temp.push(spart) //собираем только те части которые нам интересны
}
const merge = temp.join(' ').toLowerCase() // стандартизируем вывод
console.log(
Array.from(merge.matchAll(/(?<name>\w+)\s(?<val>\d+)/g))
.map(e => (Object.values({...e.groups}))) // создаем подмасивы из пар
.toString() // для компактного вывода [[k1, v1], [k2, v2], ...]
)
}
Для компактности вывода в консоли сниппета пришлось пожертвовать квадратными скобками
[ [ 'message', '42' ] ]
[ [ 'message', '42' ], [ 'part', '24' ] ]
[ [ 'order', '123' ], [ 'message', '42' ], [ 'part', '321' ] ]
[ [ 'message', '42' ], [ 'part', '34' ], [ 'order', '22' ] ]
[ [ 'order', '3' ], [ 'part', '56' ], [ 'message', '42' ] ]
[ [ 'part', '4' ] ]
[ [ 'order', '5' ] ]
В третью строку я специально добавил три 5 чтобы посмотреть на корректность работы алгоритма
Вариант через регулярку (нужна донастройка)
Основная идея - использовать негативный просмотр ?!
,
Указываем какие группы мы не ожидаем в этом месте (?!.*order.*)|(?!.*part.*)
Код:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Example {
public static void main(String[] args) {
//final String regex = "^.*?(?:(?=.*?message.+?(?<msg>[0-9]+)))?.*?(?:(?=.*?part.+?(?<part>[0-9]+)))?.*?(?:(?=.*?order.+?(?<order>[0-9]+)))?.*?$";
final String regex = "^.*?(?:(?=.*?message(?:(?!.*order.*)|(?!.*part.*)|(?:[.]id=|[ ]))(?<msg>[0-9]+)))?"
+ ".*?(?:(?=.*?part(?:(?!.*order.*)|(?!.*message.*)|(?:[.]id=|[ ]))(?<part>[0-9]+)))?"
+ ".*?(?:(?=.*?order(?:(?!.*part.*)|(?!.*message.*)|(?:[.]id=|[ ]))(?<order>[0-9]+)))?.*?$";
final String string = "abc part is created (message 42)\n"
+ "abc (message 42) part.id=24\n"
+ "abc order.id=123, (message 42) part.id=321\n"
+ "[message 42] Part with id 34 added to Order 22\n"
+ "abc Order (id=3, part.id=56) is generated \"message 42\"\n"
+ "Can't create order, becasue part 4 not found\n"
+ "Order 5 cannot be created because a part is missing";
final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Group message" + ": " + matcher.group("msg"));
System.out.println("Group part" + ": " + matcher.group("part"));
System.out.println("Group order" + ": " + matcher.group("order"));
}
}
}
Вывод:
Full match: abc part is created (message 42)
Group message: 42
Group part: null
Group order: null
Full match: abc (message 42) part.id=24
Group message: 42
Group part: 24
Group order: null
Full match: abc order.id=123, (message 42) part.id=321
Group message: 42
Group part: 321
Group order: 123
Full match: [message 42] Part with id 34 added to Order 22
Group message: 42
Group part: null // нужно доработать регулярку для with id
Group order: 22
Full match: abc Order (id=3, part.id=56) is generated "message 42"
Group message: 42
Group part: 56
Group order: null // нужно доработать регулярку для (id=3
Full match: Can't create order, becasue part 4 not found
Group message: null
Group part: 4
Group order: null
Full match: Order 5 cannot be created because a part is missing
Group message: null
Group part: null
Group order: 5
Пример доработки регулярки для конкретных случаев:
- для
Part with id
будет | with id |
- для
Order (id=3
будет | \\(id=|
экранируем скобку
Вся регулярка:
final String regex = "^.*?(?:(?=.*?message(?:(?!.*order.*)|(?!.*part.*)|(?:[.]id=| with id | \\(id=|[ ]))(?<msg>[0-9]+)))?"
+ ".*?(?:(?=.*?part(?:(?!.*order.*)|(?!.*message.*)|(?:[.]id=| with id | \\(id=|[ ]))(?<part>[0-9]+)))?"
+ ".*?(?:(?=.*?order(?:(?!.*part.*)|(?!.*message.*)|(?:[.]id=| with id | \\(id=|[ ]))(?<order>[0-9]+)))?.*?$";