StructuredStringLexer 0.0.1

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package StructuredStringLexer --version 0.0.1
                    
NuGet\Install-Package StructuredStringLexer -Version 0.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StructuredStringLexer" Version="0.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="StructuredStringLexer" Version="0.0.1" />
                    
Directory.Packages.props
<PackageReference Include="StructuredStringLexer" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add StructuredStringLexer --version 0.0.1
                    
#r "nuget: StructuredStringLexer, 0.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package StructuredStringLexer@0.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=StructuredStringLexer&version=0.0.1
                    
Install as a Cake Addin
#tool nuget:?package=StructuredStringLexer&version=0.0.1
                    
Install as a Cake Tool

StructuredStringLexer

License: MIT

概要

StructuredStringLexer<TEnum> は、正規表現を利用して、書式を持つ文字列を安全かつ確実にトークン列へ分解するための汎用文字列レクサーです。

日付書式、ファイル名テンプレート、ログファイル名テンプレートなど、語順や区切りが固定ではないが一定の書式規則を持つ文字列を、正規表現にマッチする「抽出対象トークン」と、それ以外の「解析継続トークン」に分割します。

特徴・主な機能

  • 任意の列挙型 TEnum によるトークン種別管理
  • 正規表現に一致した部分だけを指定トークン種別として抽出
  • 未一致部分を解析継続用トークンとして保持
  • 複数段階の字句解析に対応しやすい設計
  • トークン列の複製による副作用抑制
  • RegexOptions.RightToLeft を明示的に非対応化
  • 空文字マッチや逆行・重複マッチを検出する安全設計
  • SafeRegex 利用を前提にしつつ、コンパイル条件で標準 Regex に切替可能

目的

  • 書式付き文字列を、後続処理しやすいトークン列へ変換します。
  • 正規表現による部分抽出を、汎用的かつ再利用しやすい形で共通化します。
  • 日付書式、環境変数、アプリケーション独自プレースホルダーなどを段階的に解析するための基盤として利用できます。

背景

通常の Regex.Match()Regex.Matches() は、マッチした部分の抽出には便利ですが、未マッチ部分を含めて「元文字列の順序を保ったトークン列」として扱う用途では、周辺処理を自前で実装する必要があります。

StructuredStringLexer<TEnum> は、次のような処理を簡潔に扱うための内部ユーティリティです。

  • マッチ部分と未マッチ部分を交互に保持する
  • 未マッチ部分を次段階の解析対象として残す
  • トークン種別を列挙型で明示的に管理する
  • 不正な正規表現や想定外のマッチ挙動を早期に検出する

主要クラス

CharacterStringToken<TEnum>

文字列トークンを表す内部クラスです。

このクラスは、次の2つだけを保持します。

  • TokenType
    書式トークン種別
  • LexemeFormat
    書式トークンの原文

正規表現パターン化、レンダリング、出力値生成などの責務は持ちません。

StructuredStringLexer<TEnum>

文字列または既存のトークン列を、正規表現に基づいて分割する内部静的クラスです。

TEnumEnum 制約を持ち、利用側で定義した列挙型をトークン種別として使用します。

基本的な考え方

最初に、入力文字列全体を「基底トークン」として1件のトークンにします。

その後、指定した正規表現に一致する部分だけを「抽出トークン」として分離し、未一致部分は元の「解析対象トークン」として残します。

たとえば、次のような入力があるとします。

log_%yyyy%_%MM%_%dd%.txt

日付書式部分を抽出する正規表現を適用すると、概念的には次のようなトークン列になります。

[Literal] log_
[DatePattern] %yyyy%
[Literal] _
[DatePattern] %MM%
[Literal] _
[DatePattern] %dd%
[Literal] .txt

このように、元文字列の順序を保ったまま、意味のある単位に分割できます。

使い方

トークン種別の例

internal enum TokenType
{
    Literal,
    DatePattern,
    EnvironmentVariable,
    AppDomainValue,
}

初期トークンの作成

var tokens = StructuredStringLexer<TokenType>.CreateInitialTokens(
    "log_%yyyy%_%MM%_%dd%.txt",
    TokenType.Literal);

正規表現による一次トークン化

var regex = new Regex("%[a-zA-Z]+%");

var tokens = StructuredStringLexer<TokenType>.Tokenize(
    "log_%yyyy%_%MM%_%dd%.txt",
    TokenType.Literal,
    TokenType.DatePattern,
    regex);

既存トークン列への追加解析

var nextTokens = StructuredStringLexer<TokenType>.Tokenize(
    tokens,
    TokenType.Literal,
    TokenType.EnvironmentVariable,
    environmentVariableRegex);

この形式により、以下のような段階的解析が可能になります。

  1. 日付書式を抽出する
  2. 環境変数書式を抽出する
  3. アプリケーション固有書式を抽出する
  4. 最終的なレンダリング処理へ渡す

処理仕様

CreateInitialTokens()

入力文字列全体を、指定された基底トークン種別の1トークンとして返します。

internal static List<CharacterStringToken<TEnum>> CreateInitialTokens(
    string parseTokenSequence,
    TEnum baseTokenType)

Tokenize(string, TEnum, TEnum, Regex)

文字列を初期トークン化した後、指定された正規表現で一次パースします。

internal static List<CharacterStringToken<TEnum>> Tokenize(
    string parseTokenSequence,
    TEnum baseTokenType,
    TEnum extractTokenType,
    Regex regexRawChip = null)

Tokenize(List<CharacterStringToken<TEnum>>, TEnum, TEnum, Regex)

既存のトークン列に対して、指定されたトークン種別だけを解析対象にします。

internal static List<CharacterStringToken<TEnum>> Tokenize(
    List<CharacterStringToken<TEnum>> parseTokenList,
    TEnum targetTokenType,
    TEnum extractTokenType,
    Regex regexRawChip = null)

正規表現の扱い

マッチ順序

正規表現のマッチ順序は重要です。

たとえば、yyyyyy のように部分一致するパターンがある場合は、より長いパターンである yyyy を先にマッチさせる必要があります。

yy を先に抽出すると、yyyy の一部が誤って yy として分割される可能性があります。

空文字マッチ

regexRawChipnull の場合、または空文字にマッチする正規表現の場合は、解析対象トークン全体を抽出トークンとして扱います。

一方、分割処理中に match.Length == 0 となる場合は、空文字位置へのマッチとして ArgumentException を送出します。

RightToLeft 非対応

RegexOptions.RightToLeft はサポートしません。

右から左への探索では、トークン列の順序管理や未マッチ領域の扱いが複雑化し、想定した左から右への字句解析と整合しないためです。

例外仕様

条件 例外
parseTokenListnull ArgumentNullException
トークン列に null が含まれる InvalidOperationException
LexemeFormat が未設定または空文字 InvalidOperationException
regexRawChip が必要な場面で null ArgumentException
RegexOptions.RightToLeft が指定されている NotSupportedException
正規表現が空文字位置にマッチする ArgumentException
マッチ範囲が重複または逆行する InvalidOperationException

設計上の責務分離

StructuredStringLexer<TEnum> は、字句解析だけを担当します。

このクラスが担当するものは次の通りです。

  • 入力文字列の分割
  • トークン種別の付与
  • マッチ部分と未マッチ部分の保持
  • トークン列の順序維持
  • 不正なマッチ状態の検出

一方で、次の責務は持ちません。

  • トークン値のレンダリング
  • 日付や環境変数などの値解決
  • 出力パスの生成
  • 正規表現パターンそのものの構築
  • ユーザー向け API の提供

想定用途

  • ファイルパステンプレートの解析
  • ログファイル名テンプレートの解析
  • 日付書式を含む文字列の分解
  • 環境変数プレースホルダーの抽出
  • アプリケーション固有トークンの段階的解析
  • 複数種類の書式チップを順番に抽出する前処理

既知の制約・注意事項

  • RegexOptions.RightToLeft は非対応です。
  • 空文字にマッチする正規表現は、扱いに注意が必要です。
  • 部分一致する正規表現を複数使う場合は、長いパターン、具体的なパターンを先に適用してください。
  • 本クラスは internal のため、ライブラリ内部の実装部品として利用する想定です。
  • トークン種別が同一の場合は、解析を行わずクローンしたトークン列を返します。

実装メモ

CloneTokenList()

既存トークン列を複製します。

解析対象外のトークンや、トークン種別が同一で解析不要な場合に、元のトークン列への副作用を避ける目的で利用されます。

AppendSplitTokens()

正規表現のマッチ位置を基準に、未マッチ部分とマッチ部分を順番に追加します。

処理の流れは次の通りです。

  1. 正規表現の妥当性を確認する
  2. 最初のマッチを取得する
  3. マッチしない場合は、全体を解析対象トークンとして追加する
  4. マッチ前の未一致部分を追加する
  5. マッチ部分を抽出トークンとして追加する
  6. 次のマッチへ進む
  7. 最後に残った未一致部分を追加する

AppendToken()

空文字以外のトークンだけをリストへ追加します。

lexemeFormatnull の場合は例外を送出しますが、長さ0の文字列は追加対象外として処理されます。

ライセンス

License: MIT

  • 本プロジェクトは MIT LICENSE の下で公開されています。

免責事項

  • 本ソフトウェアは現状のまま提供され、利用に伴う責任は利用者に帰属します。
  • 開発者の所属や契約形態は、本ソフトウェアの利用条件や責任に影響しません。

貢献方法

  • 本プロジェクトは、主に個人の技術検証・公開を目的としています。恐れ入りますが、現時点では外部からのIssueやPull Requestによる貢献は受け付けておりません。ご理解のほどよろしくお願いいたします。
  • 尚、対応済機能として挙げている項目についてのバグ報告は、歓迎しております。

作者情報

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

Early preview release.