Регулярное выражение Golang: игнорировать несколько вхождений
У меня есть простая потребность. Ввод этого 9X_regexp ввода (строка): 10 20 30 40 65 45 44 67 9X_perlre 100 200 65 40 66 88 65
Мне нужно получить 9X_regular-expression все числа от 65 до 66. Проблема в том, что 9X_apache-regexp у нас есть несколько вхождений каждого предела. С 9X_go помощью регулярного выражения типа: (65).+(66) я 9X_perlre захватил 65 45 44 67 100 200 65 40 66. Но 9X_go-language я хотел бы получить только 40.
Как я мог 9X_go этого добиться?
https://regex101.com/r/9HoKxr/1
Ответ #1
Ответ на вопрос: Регулярное выражение Golang: игнорировать несколько вхождений
Похоже, вы хотите исключить совпадение «65» внутри 9X_regexes номера вашего шаблона до первого вхождения 9X_go «66»? Это немного многословно, но как насчет:
\b65((?:\s(?:\d|[1-57-9]\d|6[0-47-9]|\d{3,}))+?)\s66\b
Посмотреть 9X_regularexpression онлайн demo
\b65\s
— Начните с «65» между границей слова и символом пробела;-
(
- Открыть группу захвата;(?:\s
- Группа без захвата с константой пробельного символа;(?:\d|[1-57-9]\d|6[0-46-9]|\d{3,})
— вложенная группа без захвата, соответствующая любому целому числу, кроме «65» или «66»;)+?)
- Закройте группу без захвата и сопоставьте ее хотя бы один раз, но как можно меньше раз. Затем закройте группу захвата;
\s66\b
— Сопоставьте еще один пробел, за которым следует «66» и граница слова.
Примечание:
- Мы будем обрабатывать начальные пробелы с помощью функции
Trim()
через пакет strings; - Что в моих примерах я использовал «10 20 30 40 65 45 44 40 66 200 65 40 66 88 65», что должно возвращать несколько совпадений. В таком случае установлено, что OP ищет «самую короткую» совпадающую подстроку;
- Под «кратчайшим» подразумевается, что мы ищем наименьшее количество элементов, когда подстрока разделена пробелами (используя функцию 'Fields' из упомянутого выше пакета строк). Поэтому «123456» предпочтительнее «1 2 3», несмотря на то, что это «более длинная» подстрока с точки зрения символов;
Попробуйте:
package main import ( "fmt" "regexp" "strings" ) func main() { s := `10 20 30 40 65 45 44 40 66 200 65 40 66 88 65` re := regexp.MustCompile(`\b65((?:\s(?:\d|[1-57-9]\d|6[0-47-9]|\d{3,}))+?)\s66\b`) matches := re.FindAllStringSubmatch(s, -1) // Retrieve all matches shortest := `` for i, _ := range matches { // Loop over array if shortest == `` || len(strings.Fields(matches[i][1])) < len(strings.Fields(shortest)) { shortest = strings.Trim(matches[i][1], ` `) } } fmt.Println(shortest) }
Попробуйте сами here.
-
6
-
5
-
2
-
4
-
4
-
4
-
5
-
3
-
1
-
2
-
3
-
1
-
7
-
1
-
2
-
1
-
3
-
4
-
3
-
1
-
1
-
2
-
1
-
1
-
2
-
1
-
1
-
1
-
10
-
2
-
5
-
23
-
4
-
15
-
1
-
10
-
9
-
5
-
5
-
7
-
14
-
2
-
10
-
6
-
9
-
6
-
5
-
8
-
6
-
3