регулярные выражения в программном коде
Модератор: Olej
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
регулярные выражения в программном коде
Это, в каком-то смысле, продолжение темы регулярные выражения в C/C++.
И публикации по её мотивам разошедшейся по Интернет под названием "Регулярные выражения C/C++", про которую (и ссылки) описано здесь: Локализация и регулярные выражения, C/C++.
И публикации по её мотивам разошедшейся по Интернет под названием "Регулярные выражения C/C++", про которую (и ссылки) описано здесь: Локализация и регулярные выражения, C/C++.
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Но!

1. Всё это было написано максимум в 2016 году ... кой чего можно бы добавить;
2. Это было только про регулярные выражения в коде C и C++ ... нужно дополнить коротко по состоянию дел в новых (современных) языках: Python, Go, Rust, Kotlin ...
3. С акцентом на использование (или на ограничения) регулярных выражений применительно к локализованным (в частности к русскоязычным) строкам.
Немало...
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в коде
Python.
Ещё в начале этого года я бы рассматривал этот вопрос начиная с Python 2 ...
Но в 2022 году произошло очень большое (для меня, как по мне) событие: в основных дистрибутивах Linux, как итог 14-летних усилий (не так просто это оказалось!) дефаултной версией стал Python 3, и даже Python 2 по умолчанию не установлен в инсталляции, хотя и присутствует в стандартном репозитории для ручной установки ... см. Python: версии языка.
Т.е. это конец 22 летней истории Python 2.
Будем говорить только про Python 3 !
Код: Выделить всё
olej@R420:~$ python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.__version__
'2.2.1'
>>> quit()
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Обработка текстовой информации вообще, и регулярные выражения как самый мощный механизм такой обработки, всё это очень органично вписывается в области использования Python. Поэтому ничего удивительного в том, что поддержка регулярных выражений входят в Python давно и естественным образом.
В Python работа с регулярными выражениями реализована в стандартном модуле re, который входит в стандартный дистрибутив Python (т. е. Ничего не нужно специально предпринимать для его использования):
Код: Выделить всё
$ python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.__version__
'2.2.1'
>>> quit()
Код: Выделить всё
$ cat regexp.py
#!/usr/bin/python3
import re
match = re.search(r'\d\d\D\d\d', r'Телефон 123-12-12')
print(match[0] if match else 'Not found')
match = re.search(r'\d\d\D\d\d', r'Телефон 1231212')
print(match[0] if match else 'Not found')
match = re.fullmatch(r'\d\d\D\d\d', r'12-12')
print('YES' if match else 'NO')
match = re.fullmatch(r'\d\d\D\d\d', r'Т. 12-12')
print('YES' if match else 'NO')
print(re.split(r'\W+', 'Где, скажите мне, мои очки??!'))
print(re.findall(r'\d\d\.\d\d\.\d{4}',
r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017'))
for m in re.finditer(r'\d\d\.\d\d\.\d{4}', r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017'):
print('Дата', m[0], 'начинается с позиции', m.start())
print(re.sub(r'\d\d\.\d\d\.\d{4}',
r'DD.MM.YYYY',
r'Эта строка написана 19.01.2018, а могла бы и 01.09.2017'))
Код: Выделить всё
$ ./regexp.py
23-12
Not found
YES
NO
['Где', 'скажите', 'мне', 'мои', 'очки', '']
['19.01.2018', '01.09.2017']
Дата 19.01.2018 начинается с позиции 20
Дата 01.09.2017 начинается с позиции 45
Эта строка написана DD.MM.YYYY, а могла бы и DD.MM.YYYY
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Если шаблон регулярного выражения предстоит использовать неоднократно, его полезно предварительно компилировать (как уже было сказано ранее):
Код: Выделить всё
$ python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> regex = re.compile('\s+')
>>> regex.split('А роза упала на лапу Азора')
['А', 'роза', 'упала', 'на', 'лапу', 'Азора']
>>> type(regex)
<class 're.Pattern'>
Код: Выделить всё
$ python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> text = """
... 100 ИНФ Информатика
... 213 МАТ Математика
... 156 АНГ Английский
... """
>>> import re
>>> regex_num = re.compile('\d+')
>>> regex_num.findall(text)
['100', '213', '156']
>>>
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Go
Язык Go (компилирующий) в значительной мере является продолжателем линии языка C (и у основания этих языков стоят одни и те же лица, только с разрывом в 40 лет). Но, в противовес C/C++, язык Go изначально вводит для обработки символьной информации встроенный (builtin) тип строки string и обширный API строчной обработки. Поэтому язык никак не мог оставить в стороне работу с регулярными выражениями — GoLang имеет в своей стандартной библиотеке надежный пакет выражений, пакет regexp.
Код: Выделить всё
$ cat regexp.go
package main
import ("fmt"; "regexp")
func main() {
matched, _ := regexp.MatchString("cat", "black cat meow")
fmt.Println(matched)
re, _ := regexp.Compile("cat")
res := re.FindAllString("black cat meowcat", -1)
fmt.Println(res)
}

И выполнение:
Код: Выделить всё
$ go run regexp.go
true
[cat cat]
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Rust
Несмотря на то, что Rust ориентирован во многом как язык системного программирования, но и в нём, примерно с 2014 года, было введено библиотечное расширение (crate в терминологии Rust) regex. Это лишний раз указывает на то какую оценку такой технике дают разработчики языков.
Но в Rust всё гораздо хуже с использованием по сравнению с предыдущими... Т.е. по подключению крейта (библиотеки в терминологии Rust) regex:
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ rustc regex1.rs
error[E0432]: unresolved import `regex`
--> regex1.rs:2:5
|
2 | use regex::Regex;
| ^^^^^ maybe a missing crate `regex`?
|
= help: consider adding `extern crate regex` to use the `regex` crate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Я не знаю как подключить внешний крейт regex (как и любой другой библиотечный крейт!) используя консольный компилятор rustc :
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ which rustc
/home/olej/.cargo/bin/rustc
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ rustc -V
rustc 1.64.0 (a55dd71d5 2022-09-19)
Которым компилировал простейшие коды Rust: Rust: новый подход к снаряду....
И, похоже, что этого не знают очень многие обсуждающие: Is it possible to use external crates like regex without cargo?
Это само по себе очень интересный вопрос, который нужно разрешить ... там в теме относительно Rust.Does anyone know of a way to get a program to compile with only rustc and use external crates?, even if I have to manually download the crates source that is fine.
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Но зато я знаю как создать проект с помощью менеджера проектов Rust cargo + как подключать к нему любые библиотечные крейты по зависимостям...
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ which cargo
/home/olej/.cargo/bin/cargo
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo -V
cargo 1.64.0 (387270bc7 2022-09-16)
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo new regexrs1
Created binary (application) `regexrs1` package
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ tree regexrs1
regexrs1
├── Cargo.toml
└── src
└── main.rs
1 directory, 2 files
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cat regexrs1/Cargo.toml
[package]
name = "regexrs1"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cat regexrs1/src/main.rs
fn main() {
println!("Hello, world!");
}
- Olej
- Писатель
- Сообщения: 18788
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: регулярные выражения в программном коде
Подключаю библиотечный крейт:
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo search regex
regex = "1.7.0" # An implementation of regular expressions for Rust. This implementation uses finite automata …
lazy-regex = "2.3.1" # lazy static regular expressions checked at compile time
proc-macro-regex = "1.1.0" # A proc macro regex library
regex-automata = "0.2.0" # Automata construction and matching using regular expressions.
easy-regex = "0.11.7" # Make long regular expressions like pseudocodes
readable-regex = "0.1.0-alpha1" # Regex made for humans. Wrapper to build regexes in a verbose style.
human_regex = "0.2.3" # A regex library for humans
regex_static = "0.1.1" # Compile-time validated regex, with convenience functions for lazy and static regexes.
webforms = "0.2.2" # Provides form validation for web forms
hashtag-regex = "0.1.1" # A simple regex matching hashtags accoding to the unicode spec: http://unicode.org/reports/tr…
... and 887 crates more (use --limit N to see more)
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cat regexrs1/Cargo.toml
[package]
name = "regexrs1"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "1.7"
Код: Выделить всё
olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cat regexrs1/src/main.rs
use regex::Regex;
fn main() {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
assert!(re.is_match("2014-01-01"));
}

Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость