LCOV - code coverage report
Current view: top level - src - regexp_tokenizer.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 14 14
Test Date: 2026-07-06 21:47:03 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2026 The Authors
       2              : //
       3              : // Licensed under the Apache License, Version 2.0 (the "License");
       4              : // you may not use this file except in compliance with the License.
       5              : // You may obtain a copy of the License at
       6              : //
       7              : //     https://www.apache.org/licenses/LICENSE-2.0
       8              : //
       9              : // Unless required by applicable law or agreed to in writing, software
      10              : // distributed under the License is distributed on an "AS IS" BASIS,
      11              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12              : // See the License for the specific language governing permissions and
      13              : // limitations under the License.
      14              : 
      15              : import 'tokenizer.dart';
      16              : 
      17              : /// The pure-Dart [Tokenizer] implementation, using [RegExp] for word boundary
      18              : /// detection.
      19              : ///
      20              : /// ## Scope — English and Latin scripts
      21              : ///
      22              : /// This implementation is sufficient for English-language prose and common
      23              : /// technical identifiers (`mTLS`, `0x8004210B`, etc.). It is **not** suitable
      24              : /// for non-Latin scripts (CJK, Thai, Arabic, etc.) where word boundaries do
      25              : /// not follow whitespace rules. For those use cases, prefer [IcuTokenizer],
      26              : /// which uses the system ICU library and conforms to UAX #29 Unicode Text
      27              : /// Segmentation. The [Tokenizer] interface makes that swap transparent to the
      28              : /// calling pipeline.
      29              : ///
      30              : /// ## Example
      31              : ///
      32              : /// ```dart
      33              : /// final tokenizer = RegExpTokenizer();
      34              : /// print(tokenizer.tokenise('Hello, world!')); // ['Hello', 'world']
      35              : /// print(tokenizer.tokenise('')); // []
      36              : /// print(tokenizer.tokenise('mTLS handshake')); // ['mTLS', 'handshake']
      37              : /// ```
      38              : class RegExpTokenizer implements OffsetTokenizer {
      39              :   /// Creates a new [RegExpTokenizer].
      40            3 :   const RegExpTokenizer();
      41              : 
      42              :   /// Matches sequences of Unicode word characters (letters, digits, and
      43              :   /// underscores), optionally allowing internal hyphens and apostrophes so
      44              :   /// that contractions and hyphenated terms are kept intact.
      45              :   ///
      46              :   /// `\w` in Dart's RegExp engine matches `[a-zA-Z0-9_]` only (ASCII).
      47              :   /// For broader Unicode letter support we use `\p{L}` and `\p{N}` with the
      48              :   /// `unicode` flag.
      49            9 :   static final _wordPattern = RegExp(
      50              :     r"[\p{L}\p{N}][\p{L}\p{N}_'\-]*[\p{L}\p{N}]|[\p{L}\p{N}]",
      51              :     unicode: true,
      52              :   );
      53              : 
      54            3 :   @override
      55              :   List<String> tokenise(String text) {
      56            3 :     if (text.isEmpty) return const [];
      57            3 :     return _wordPattern
      58            3 :         .allMatches(text)
      59            9 :         .map((m) => m.group(0)!)
      60            3 :         .toList(growable: false);
      61              :   }
      62              : 
      63            1 :   @override
      64              :   List<TokenSpan> tokeniseSpans(String text) {
      65            1 :     if (text.isEmpty) return const [];
      66            1 :     return _wordPattern
      67            1 :         .allMatches(text)
      68            6 :         .map((m) => TokenSpan(m.group(0)!, m.start, m.end))
      69            1 :         .toList(growable: false);
      70              :   }
      71              : }
        

Generated by: LCOV version 2.0-1