регулярные выражения в программном коде

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 10:01

Olej писал(а):
26 дек 2022, 23:46
C Rusr пришлось сильно попотеть ...
Разработчики Rust, как уже было замечено ранее, уделяют исключительное внимание производительности кода Rust (и преуспевают в этом: временами скорость приложений Rusr больше чем у эквивалентных GCC приложений C/C++!). С другой стороны, компиляция шаблонов регулярных выражений — это крайне большой объём работы, особенно для сложных шаблонов, это построение кода решающего автомата, как было замечено выше.
Но, в подавляющем большинстве практических случаев, полный вид шаблона регулярного выражения известен (и выверен) уже к началу написания кода, зачастую уже к этому времени мы знаем синтаксис тех текстовых строк которые предстоит анализировать. А если это так, то шаблон регулярного выражения можно скомпилировать ещё до начала выполнения программы.
Это из моего текста ... - Сам себя с утра не зацитируешь, считай, весь день пропал :lol:
Это то что они называют статическая компиляция.
Вот что пишет один из разработчиков Rust (перевод мой, прошу прощения ;-) ):
Я решительно не имею в виду компиляцию регулярных выражений «заранее». Я имею в виду более буквальный перевод: регулярное выражение преобразуется в собственный код Rust, когда вы компилируете свою программу на Rust. То есть существует (практически) нулевая стоимость компиляции регулярного выражения во время выполнения. Возможно, что более важно, поскольку он скомпилирован в собственный код Rust, ваше регулярное выражение всегда будет работать быстрее.
А резонно же :!:

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 10:07

Olej писал(а):
27 дек 2022, 10:01
Это то что они называют статическая компиляция.
Для реализации такой возможности используется библиотека (крейт) lazy_static.
Делаю новый проект...

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo new regexrs3
     Created binary (application) `regexrs3` package

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cd regexrs3

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ cargo add lazy_static
    Updating crates.io index
      Adding lazy_static v1.4.0 to dependencies.
             Features:
             - spin
             - spin_no_std

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ cargo add regex
    Updating crates.io index
      Adding regex v1.7.0 to dependencies.
             Features:
             + aho-corasick
             + memchr
             + perf
             + perf-cache
             + perf-dfa
             + perf-inline
             + perf-literal
             + std
             + unicode
             + unicode-age
             + unicode-bool
             + unicode-case
             + unicode-gencat
             + unicode-perl
             + unicode-script
             + unicode-segment
             - pattern
             - unstable
             - use_std

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ cargo clean
Сборка:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ cargo build
   Compiling memchr v2.5.0
   Compiling regex-syntax v0.6.28
   Compiling lazy_static v1.4.0
   Compiling aho-corasick v0.7.20
   Compiling regex v1.7.0
   Compiling regexrs3 v0.1.0 (/home/olej/2022/own.BOOKs/Localiz/regex.cod/regexrs3)
    Finished dev [unoptimized + debuginfo] target(s) in 7.02s

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ ls -l ./target/debug/regexrs3
-rwxrwxr-x 2 olej olej 16322296 дек 27 01:20 ./target/debug/regexrs3

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ file target/debug/regexrs3
target/debug/regexrs3: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9b2884baab8d7c483bc2a8d990f234079081ae0a, for GNU/Linux 3.2.0, with debug_info, not stripped

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ ldd target/debug/regexrs3
    linux-vdso.so.1 (0x00007ffe791a7000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f89a78a2000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f89a787f000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f89a7879000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f89a7687000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f89a7bfd000)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 10:15

Olej писал(а):
27 дек 2022, 10:07
Делаю новый проект...
Предварительно, перед сборкой, меняю код предыдущего проекта на:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ cat src/main.rs 
use std::io;
use lazy_static::lazy_static;
use regex::Regex;

lazy_static! {
   static ref RE: Regex = Regex::new(r"\d\d\d").unwrap();
}

fn main() {
   loop {
      let mut input = String::new();
      io::stdin().read_line(&mut input).expect("ошибка ввода");
      if 1 == input.len() { break }; // выход
      let buf = &input[0 .. input.len() - 1];
      if 0 == RE.captures_iter(buf).count() {
         println!("no match found");
         println!("--------------------");
         continue;
      }
      for caps in RE.captures_iter(buf) {
         for i in 0..caps.len() {
            let cap = caps.get(i).unwrap();
            println!("{}/{} : {}",
                     cap.start(), cap.end(), cap.as_str());
         }
      }
      println!("--------------------");
   }
}
Вложения
main.rs
(803 байт) 22 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 10:17

Olej писал(а):
27 дек 2022, 10:07
Сборка:
Выполнение:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod/regexrs3$ ./target/debug/regexrs3
567
0/3 : 567
--------------------
67
no match found
--------------------
5A7
no match found
--------------------
123456
0/3 : 123
3/6 : 456
--------------------
Всё как доктор прописал! :-D

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 10:21

Olej писал(а):
15 дек 2022, 01:17
нужно дополнить коротко по состоянию дел в новых (современных) языках: Python, Go, Rust, Kotlin ...
Остаётся Kotlin...
Нужно вспомнить что там в нём делается:
Kotlin: установка и использование
Kotlin: игры с кодом - здесь про то как компилировать код + как его потом запускать.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 19:27

Olej писал(а):
27 дек 2022, 10:21
Остаётся Kotlin...
Kotlin
Сделал.

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cat regexk1.kt 
import kotlin.system.*

fun main(args: Array<String>) {
    val pattern : String = args[0]
    val regex = pattern.toRegex()
    while (true) {
        var ввод : String = readln()
        if (0 == ввод.length)  // выход
            exitProcess(0)            
        var matches : Sequence<MatchResult>? = regex.findAll(ввод)
        if (!matches!!.any()) {
            println("no match found")
            println("--------------------")
            continue
        }
        for (match in matches)
            for (grp in match.groups)
                println("${grp?.range?.first}/${grp?.range?.last} : ${grp?.value}")
        println("--------------------")
    }
}
Вложения
regexk1.kt
(690 байт) 23 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 22:50

Olej писал(а):
27 дек 2022, 19:27
Сделал.
Компиляция:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ kotlinc regexk1.kt -include-runtime -d regexk1.jar
Выполнение:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ java -jar regexk1.jar "(\d)(\d\d)"
== 987 == 654
3/5 : 987
3/3 : 9
4/5 : 87
10/12 : 654
10/10 : 6
11/12 : 54
--------------------
c1v2n3
no match found
--------------------
Для сравнения - то же, что чуть раньше было показано на C++:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ./regexg2 "(\d)(\d\d)"
== 987 == 654
3/6 : 987
3/4 : 9
4/6 : 87
10/13 : 654
10/11 : 6
11/13 : 54
--------------------

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 27 дек 2022, 22:51

Olej писал(а):
27 дек 2022, 22:50
Для сравнения - то же, что чуть раньше было показано на C++:
1. Так тот, так и другой вариант считает позиции в текстовой строке UTF-8 по символам, но не по байтам.
2. Конечная позиция каждого сопоставления в варианте Kotlin не 1 меньше чем в варианте C++. Но это связано только с тем, что библиотека Kotlin предоставляет финальную позицию как «последний символ строки», а в C++ — как «байт за окончанием строки», терминальный байт '\0'… При желании то и другое можно поправить, если хорошо понимать откуда берутся эти цифры.
3. Но из-за такой вот дуальности, а также понимания того откуда она происходит, я менять код пока не буду… «у каждой избушки свои погремушки».

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 28 дек 2022, 00:05

Olej писал(а):
27 дек 2022, 19:27
Kotlin
Сделал
Запускать можно 3-мя способами (может ещё есть?):

1. Использовать JVM среды Java:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ kotlinc regexk1.kt -include-runtime -d regexk1.jar

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ./regexg2 "(\d)(\d\d)"
== 987 == 654
3/6 : 987
3/4 : 9
4/6 : 87
10/13 : 654
10/11 : 6
11/13 : 54
--------------------
2. Компилировать и использовать среду Kotlin без использования JVM:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ kotlinc regexk1.kt -d regexk1k.jar

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ jar tf regexk1k.jar
META-INF/MANIFEST.MF
Regexk1Kt.class
META-INF/main.kotlin_module

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ kotlin -classpath regexk1k.jar Regexk1Kt "(\d)(\d\d)"
== 987 == 654
3/5 : 987
3/3 : 9
4/5 : 87
10/12 : 654
10/10 : 6
11/12 : 54
--------------------
3. Установить и использовать Kotlin Native - см. Kotlin: установка и использование...
И компилировать в нативный код Linux (Kotlin Native работает на множестве аппаратных платформ и операционных систем):

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ~/kotlin/kotlin-native/dist/bin/kotlinc-native regexk1.kt -o regexk1

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ls -l regexk1.kexe
-rwxrwxr-x 1 olej olej 2084152 дек 27 22:46 regexk1.kexe

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ file regexk1.kexe
regexk1.kexe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.16, BuildID[sha1]=35bf922f1e11448be31a25a523aaef7a6dfa741a, not stripped

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ldd regexk1.kexe
	linux-vdso.so.1 (0x00007ffc8f0ca000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9f5c8e7000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9f5c798000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9f5c775000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9f5c75a000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9f5c568000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f9f5c915000

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ./regexk1.kexe "(\d)(\d\d)"
== 987 == 654
3/5 : 987
3/3 : 9
4/5 : 87
10/12 : 654
10/10 : 6
11/12 : 54
--------------------

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: регулярные выражения в программном коде

Непрочитанное сообщение Olej » 28 дек 2022, 01:44

Olej писал(а):
28 дек 2022, 00:05
Запускать можно 3-мя способами (может ещё есть?):
В итоге:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ ls -l regexk1*
-rw-rw-r-- 1 olej olej 4694586 дек 28 00:39 regexk1.jar
-rwxrwxr-x 1 olej olej 2084152 дек 28 00:40 regexk1.kexe
-rw-rw-r-- 1 olej olej    2213 дек 28 00:39 regexk1k.jar
-rw-rw-r-- 1 olej olej     706 дек 27 22:28 regexk1.kt

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

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