แแแแแฅแแแงแแแ แกแแแแแ แแแแก แแแแแแแแแแแก แแแ แแแแ แแแ แกแแ (0.1.0). แแก แขแแฅแกแขแก แแแแแแแแชแแแก แแ แแแก แจแแแแแแแก แแแฎแแแแแ แแแฃแจแแแแแก แแแแจแแแแแแแแแแ. แจแแแแแแ แแ แคแแ แแแขแ แแฌแแ แแแ C++ แจแแแแแแแก แแ แแฃแแแแขแแ แแ แแแแแแแแ แแแแ แขแแแแ แแแฃแ แแแขแแ แแแแแกแขแฃแ แกแแกแ แฃแแ แแแขแแแแขแแ (TDFA), แ แแแแแก แแแแแแช C++ แจแแแแแแแแแก แแแแแงแแแแแแ แแแแแแแ แแแแแ แแแแแ แแแแ แแแแแแแแชแแแก แแ แแแก แแแแจแ. แจแแกแ แฃแแแแแก แจแแแแแแ แแแแฎแแแแแแ แขแแแแก แแแแจแแแแแแแ. แแ แแแฅแขแแก แแแแ แแแฌแแ แแแแ C++23-แจแ แแ แแแแ แชแแแแแฃแแแ GPLv3 แแแชแแแแแแ. import scan; // แแแแฎแแแแ แแฃ แแ แ แแแแแ แกแขแ แแฅแแแ. แแแแแแฃแแ แจแแกแแแแก แฌแแ แขแแแ แแกแแแ แแแแแแแแแแก แแแแแขแแ แแ. scan::match<ยซ[az]+@[az.]+ยป>(address); address | scan::match<ยซ[az]+@[az.]+ยป>; // แฏแแฃแคแแแแ. const auto found = scan::match<ยซ([0-9]+)-([az]+)ยป>(ยซ42-abcยป); found.get<1>().to_view(); // "42" // แแแแฃแจแแ แแแแแแแแฃแแ แกแขแ แแฅแแแแก แแแกแแฌแงแแกแ แแ แแแ แแแแ แจแแกแแแแแแกแแแ แแแแแกแแแแ แแแแแแแก. scan::starts_with<ยซ[a-z]+ยป>(ยซabc123ยป).whole().to_view(); // "abc" scan::search<ยซ[0-9]+ยป>(ยซid=4210xยป).to_view(); // "4210" // แงแแแแ แจแแกแแแแแแกแแแ แแ แแแ แจแแ แแก แแแฌแแแแแ แแแ แแแชแ แฎแแแแแแ. for (const auto& one : text | scan::search_all<ยซ[a-z]+ยป>) { โฆ } const auto fields = "a,bb,,ccc" | scan::split<ยซ,ยป> | std::ranges::to (); // แแแแจแแแแแแแแแ, แแ แ แขแแฅแกแขแ. struct row { int id; std::string_view name; }; const row one = scan::scan<ยซ{},{[a-z]+}ยป>(line); // แกแแ, แขแแแแแแก แฏแแแ, แฉแแแแแฃแแ แคแแ แแ. struct all { std::vector แแแแจแแแแแแแแแ; std::แแแ แแแแขแ tail; }; const all got = scan::scan<ยซ{{}{*,?}} {{[0-9]+}|{[a-z]+}}ยป>(ยซ1,2,3 abcยป); // แจแแงแแแแแก แแแกแแฌแงแแกแ แแ แแแกแแแ แแแ แฉแแแแแ แแแคแแ แแแชแแ. const auto [แแแแจแแแแแแแ, แแแกแแแแแแ] = scan::scan_prefix<ยซ{},{}ยป>(แฎแแแ).take (); // แแ แแ แฉแแแแฌแแ แ แแ แแแ แแฃแแแ, แแแแแกแแแแ แ แ แแแแแแ. for (const row& one : scan::each<ยซ{},{[az]+}\\nยป>(text).of ()) { โฆ }
แแแแแแแแแ, แ แแแแแก แฌแแแแแฎแแแช แแฎแแแแ แแ แแฎแแ แแ แแก แจแแกแแซแแแแแแ, แแแแแฎแแแ แแฃแคแแ แแแแชแแแก แแแ แแจแ, แแแแแแ แแ แแแแแแ แกแแแแแแแแแแก แแแกแแแแกแแแแแแ. แจแแกแแแแฎแ แกแแแแแแแแแแก แ แแแแแแแแ แแแแแกแแแฆแแ แแแ แแแแฃแจแแ แแแแแแแแชแแแก แแ แแก; แแฃ แแก แ แแชแฎแแ แแแฃแฌแแแแแแแแ, แฌแแแแแฎแแ แฃแแ แงแแคแแแแ แแแแแแแแชแแแก แแ แแก. std::istringstream source(ยซset speed 42\\nset gain 7\\nยป); source > std::noskipws; struct command { scan::held<16> name; int value; }; for (const command& one : scan::each<ยซset {[a-z]+} {[0-9]+}\\nยป>(std::views::istream (แฌแงแแ แ)) .-แแก ()) { โฆ } แจแแกแ แฃแแแแ.
แแแแแแแแแ แฉแแขแแ แแ Ryzen 9 9950X แแ แแชแแกแแ แแ, clang 22.1.8 libc++-แแ, -O3 -march=native,LTO. 32 แฉแแฌแแ แ แแแแ แแแแแแแ, แจแแแแ แแแแแแก แกแแจแฃแแแ. "([az]+),([az]+),([az]+),([az]+),([az]+)" "alpha,bravo,charlie,delta,echo" scan::scan .sentinel() 477 ns re2c 554 ns scan::scan 659 ns CTRE 717 ns RE2 15986 ns แแแแแ แฎแฃแแ แแแแ, แแแแแแฃแแจแ แแ แแกแ แแกแ scan::scan .sentinel() 57.8 ns re2c 637 ns CTRE 692 ns RE2 11751 ns "first.last@subdomain.example.com" แแแแชแแแแ, แแ แแคแแ แ แแแแซแแแแ scan::match .sentinel().scalar() 436 ns scan::match .scalar() 545 ns re2c 1186 ns RE2 2616 ns CTRE 14339 ns แฏแแฃแคแแแแก แแแจแแ แแแแ แแแแแแแแกแแก
แขแแแก แแฃแแแแแ, แ แแแแ แฏแแฃแคแก แแแแแฃแแแแแแ แจแแแแแแ แกแแแแแแ แแ แจแแคแแกแแแ แแแแแแแ แฎแแ แชแแแแแแแ: แชแแแแแก แแขแแ แแชแแแแ แแ แแแแฎแแแ, แฅแแแกแขแ แแฅแแแแแ แแ แแฅแแแแแ. struct tally { unsigned long value = 0; }; struct reading { tally number; std::string_view tail; }; template <> struct scan::scanner { static constexpr std::string_view pattern() { return R"(\\(((_+)(X|Y)*)*\\))"; } struct state_type { unsigned long total = 0; unsigned place = 0, marks = 0; }; static constexpr state_type begin_groups() { return {}; } static constexpr void opened_group(state_type& one, scan::group_at<0>) { one.place = 0; one.marks = 0; } static constexpr void closed_group(state_type& one, scan::group_at<0>) { unsigned long weight = 1; for (unsigned step = 1; step < one.place; ++step) weight *= 10; one.total += weight * one.marks; } static constexpr void push_group(state_type& one, scan::group_at<1>, char) { ++one.place; } static constexpr void push_group(state_type& one, scan::group_at<2>, char แแกแ) { one.marks += แแกแ == 'Y' ? 2u: 1u; } static constexpr tally finish_groups(state_type one) { return {one.total}; } }; const reading got = scan::scan<โแแแแจแแแแแแแ={}{[az]*}โ>(โแแแแจแแแแแแแ=(__X_XX)abcdefghโ).of (); // got.number.value == 12, got.tail == "abcdefgh"
แแแแแกแแแแ แ แแแแแแซแแฎแแแแแ แแแแแฅแขแ - แแแแแแขแแ แ, แแฃแแ, แแ แแแ, แ แแช แแ แฃแแแ แแงแแก - แจแแแซแแแแ แแแแแแชแแก แแแแจแแแแแแแแก แจแแแฅแแแแ แแแแแซแแฎแแแแก. แแแแขแแฅแกแขแแก แขแแแ แแ แแแแ แแแแ: แกแแแแแ แแก แแแแแแแ แแแแ แแ แแแกแ แแแแแแฃแแ แฐแฃแแ แจแแแซแแแแ แจแแแแแแแ แแแฃแแ แแงแแก แแแกแแ, แแแแขแแ แกแแแแแ แจแ แแ แชแแ แแ แแแแแแซแแฎแแแแแ แขแแแ แแ แแ แแก แแแฎแกแแแแแ. struct arena { std::pmr::memory_resource* where = nullptr; std::pmr::memory_resource* resource() const { return where; } }; struct numbers { std::pmr::vector แแแแจแแแแแแแแแ; }; struct both { แ แแชแฎแแแแ แแแ แชแฎแแแ; แ แแชแฎแแแแ แแแ แฏแแแแ; }; template <> struct scan::scanner { แกแขแแขแแแฃแ แ constexpr std::string_view pattern() { return "([0-9]+)(?:,([0-9]+))*"; } แจแแแแแแ แกแขแ แฃแฅแขแฃแ แแก แแแแแแแ แแแแ { std::pmr::vector แแแแจแแแแแแแแแ; int running = 0; }; แกแขแแขแแแฃแ แ แแแแแแแ แแแแ begin_groups() { return {}; } แจแแแแแแ แแแแแฎแแแก แแแแแฎแแแก(const Told& แแ แแ) { one.resource(); } แกแขแแขแแแฃแ แ แแแแแแแ แแแแ begin_groups(const Told& told) { return {std::pmr::vector}}} (told.resource()), 0}; } แจแแแแแแ แกแขแแขแแแฃแ แ void push_group(state & แแ แแ, แกแแแแแ แแแ::group_at , char แชแแคแ แ) { one.running = one.running * 10 + (แชแแคแ แ - '0'); } แจแแแแแแ แกแขแแขแแแฃแ แ void closed_group(state) & แแ แแ, แกแแแแแ แแแ::group_at ) { one.values.push_back(one.running); one.running = 0; } แจแแแแแแ แกแขแแขแแแฃแ แ แ แแชแฎแแแแ finish_groups(state แแ แแ) { return {std::move(one.values)}; } }; std::pmr::monotonic_buffer_resource bytes; const arena mine{&bytes}; scan::scan<โ{} {}โ>(แขแแฅแกแขแ).of (แฉแแแ); // แแ แแ แแ แแแ แแแแแแแกแแแแก scan::scan<ยซ{} {}ยป>(แขแแฅแกแขแ).of (แฉแแแ, scan::default_context); // แแ แแ แแแแ แแแแแแแ scan::scan<โ{} {}โ>(แขแแฅแกแขแ).of ({mine, scan::default_context}); // แคแ แฉแฎแแแแแจแ แแแแแ const both got = scan::scan<ยซ{} {}ยป>(text).with(mine); // แแแแขแแฅแกแขแ แแ แฃแแแ แแงแแก แแแกแ แขแแแ: แแแแแแขแแ แ แแฆแฌแแแก // read.struct two { std::pmr::string name; std::pmr::string tail; }; const two keeped = scan::scan<ยซ{[az]+} {[az]+}ยป>(text).of<( std::pmr::polymorphic_allocator<>(&bytes));
แแแฃแญแ แแแแแ แแฆแแแก แแแแแแซแแฎแแแแแก แแแแแฅแขแก แแ แแ แ แแกแแก, แแแแขแแ แแแแแแแ แแแแแก แจแแฃแซแแแ แแแกแ แแแกแแแแ แแแก แจแแแแฎแแ: แแแแขแแฅแกแขแ แแแฅแแแแแแก แแแ แแก แฎแแแแ แซแแแแแแแแแ แแ แงแแแแ แฌแแแแแฎแแ แฎแแแแ แแ แแแ แแก แคแแ แแแแแจแ. แกแฎแแ แแแฎแแกแแแแแแแแแ
- แแ แ แคแแแ: แจแแแแแแแก แคแแแ (match, starts_with, search, search_all, split) แแ แคแแ แแแขแแก แคแแแ, แกแแแแช "{}" แแ แแก แแแแ, แฎแแแ แแแแแแแก แแแแจแแแแแแแ แแแแแกแแแฆแแ แแแ แแแแแ แขแแแแก แแแแแแแ.
- แแแแแแแฃแแชแแแก แฌแแกแ แแแ แชแฎแแแ-แแแ แแแแแแแ, แ แแแแ แช Perl-แจแ, RE2-แกแ แแ CTRE-แจแ.
- แงแแแแ แแแแแ แฉแแแแแแแแแ แแกแแแ แแฃแจแแแแก แแฃแแแแ แแแแแกแแฎแฃแแแแแแจแ.
- แแ แแ แกแแแแแก แแแแแฎแแแแแก แแแ แแแแขแแแ, แฃแแฃ แแแแแ แแแแแ แแ แฃแแแแแแแก แแแแกแแแแแ; แจแแแแแแแแ แแแแขแแแแ แแฃแจแแแแแ.
- แแฎแแแแ แแแจแแแแแก แแ แแก แชแแแแแแ แแแแฃแจแแแ แแ แแ แแก แแฎแแ แแแญแแ แแแ.
แแกแแแแแแ
แแแแแแแแชแแ แฎแแแแ clang-แแกแ แแ GCC-แแก แแแแแงแแแแแแ. C++ แแแแฃแแแแ แแ แแกแแแแแแแแฃแแแ: แฎแแแแแกแแฌแแแแแแ แแแแแแฃแแแแแขแแ แแก แแแแ แแแแแ แแแแฃแแแแแแแ แแแแแ แแ แแแฃแแ แกแแแแฃแ แแก แคแแแแแแ (include/) - แแแแแแฃแแ แแแแแแแ แแแแแจแแ แแแก, แแแแแจแแ แแแก แแ แแแแกแขแฃแ แแแก แแแ. แแ แแแแแ แแ แแแแแแแแแแฃแแแแ, Boost.PFR, แแ แแ แแก แกแแญแแ แ, แ แแแแกแแช C++26 binding packs แฉแแ แแฃแแแ. FetchContent_Declare(scan GIT_REPOSITORY https://github.com/j4niwzis/scan.git GIT_TAG v0.1.0) FetchContent_MakeAvailable(scan) target_link_libraries(mine PRIVATE scan::scan)
แฌแงแแ แ: opennet.ru
