Регулярное выражение Golang: игнорировать несколько вхождений
У меня есть простая потребность. Ввод этого 9X_regex-php ввода (строка): 10 20 30 40 65 45 44 67 9X_regex 100 200 65 40 66 88 65
Мне нужно получить 9X_regular-expression все числа от 65 до 66. Проблема в том, что 9X_regexp у нас есть несколько вхождений каждого предела. С 9X_regex помощью регулярного выражения типа: (65).+(66) я 9X_regularexpression захватил 65 45 44 67 100 200 65 40 66. Но 9X_golang я хотел бы получить только 40.
Как я мог 9X_regexp этого добиться?
Ответ #1
Ответ на вопрос: Регулярное выражение Golang: игнорировать несколько вхождений
Похоже, вы хотите исключить совпадение «65» внутри 9X_regexp номера вашего шаблона до первого вхождения 9X_apache-regexp «66»? Это немного многословно, но как насчет:
\b65((?:\s(?:\d|[1-57-9]\d|6[0-47-9]|\d{3,}))+?)\s66\b
Посмотреть 9X_perl-regex онлайн 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