🟩 もくじ

●●● Windows環境再構築中につき、記事が工事中 ●●●

■ 正規表現における量指定子と使用例(基本パターン + 最小マッチ)

【1】+:1回以上の繰り返し(貪欲)

  • 正規表現:a+
  • 対象文字列:aaab
  • マッチ結果:aaa 👉 a が1回以上続く部分を、できる限り多くマッチします。

【2】*:0回以上の繰り返し(貪欲)

  • 正規表現:a*
  • 対象文字列:aaab
  • マッチ結果:aaa 👉 a が0回以上繰り返される部分にマッチ。何もない部分にもマッチ可能。

【3】?:0回または1回の繰り返し

  • 正規表現:a?
  • 対象文字列:aaab
  • マッチ結果(全体検索時):a, a, a, ""(空文字) 👉 各位置において a が1つあればマッチ。なければ空でもマッチします。

【4】{n}:ちょうどn回の繰り返し

  • 正規表現:a{3}
  • 対象文字列:aaabaaa
  • マッチ結果:aaa 👉 a がちょうど3回連続している部分にのみマッチ。

【5】{m,n}:m回以上、n回以下の繰り返し

  • 正規表現:a{2,4}
  • 対象文字列:aaaaab
  • マッチ結果:aaaa(貪欲なので最大限マッチ)

【5-1】{,n}:0回以上、n回以下の繰り返し({0,n} と同義)

  • 正規表現:a{,2}
  • 対象文字列:aaa
  • マッチ結果(全体検索時):aa, a

【5-2】{m,}:m回以上の繰り返し

  • 正規表現:a{2,}
  • 対象文字列:aaaaa
  • マッチ結果:aaaaa

■ 最小マッチ(非貪欲)指定付きの量指定子と使用例

〔1〕+?:1回以上、できるだけ少なくマッチ

  • 正規表現:a+?
  • 対象文字列:aaab
  • マッチ結果(全体検索時):a, a, a 👉 貪欲だと1回で aaa にマッチするが、最小マッチでは1文字ずつ分割されます。

〔2〕*?:0回以上、できるだけ少なくマッチ

  • 正規表現:a*?
  • 対象文字列:aaab
  • マッチ結果(全体検索時):"", "", "", "", ""(5つ) 👉 a を0回で済ませるのが最小なので、すべての位置で空文字にマッチ。

〔3〕??:0回または1回、できるだけマッチしない

  • 正規表現:a??
  • 対象文字列:aaab
  • マッチ結果(全体検索時):"", "", "", "", ""(5つ) 👉 貪欲な a? なら a にマッチするが、a?? は空文字優先。

〔4〕{n}?:ちょうどn回(※最小マッチの意味はない)

  • 正規表現:a{3}?
  • 対象文字列:aaab
  • マッチ結果:aaa 👉 {3} は「ちょうど3回」なので、最小/最大の概念は関係ない。? は無意味。

〔5〕{m,n}?:m回以上n回以下、できるだけ少なくマッチ

  • 正規表現:a{2,4}?
  • 対象文字列:aaaaa
  • マッチ結果:aa 👉 a を2〜4回の間で、最小(2回)だけマッチ。

〔5-1〕{,n}?:0回以上n回以下、できるだけ少なくマッチ

  • 正規表現:a{,3}?
  • 対象文字列:aaaaa
  • マッチ結果(全体検索時):"", "", … 👉 最小なので0回でマッチする位置が優先される。

〔5-2〕{m,}?:m回以上、できるだけ少なくマッチ

  • 正規表現:a{2,}?
  • 対象文字列:aaaaa
  • マッチ結果:aa 👉 a が2回以上の中で**最小(2回)**だけマッチ。

✅ 最後にポイントまとめ:

  • {n}? は構文的には正しいが、意味が変わらないため非実用的。
  • 実際の処理や抽出で「最小限に抑えたい」場合は、+?*?{m,n}? を多用。
  • パターンの設計では、データの構造(区切り文字・境界など)と合わせて使うことが重要。

必要に応じて、これらの正規表現を含むコード(Python、JavaScriptなど)やツール(例:grep、VS Codeの検索)での活用例も紹介できます。どの環境で使う予定ですか?

  • 【1】+:直前の1文字の1回以上の繰り返し
  • 【2】*:直前の1文字の0回以上の繰り返し
  • 【3】?:直前の1文字の0回または1回の繰り返し
  • 【4】{n}:直前の1文字のn回の繰り返し
  • 【5】{m,n}:直前の1文字のm回以上、n回以下の繰り返し
    • 【5-1】{,n}:直前の1文字の0回以上、n回以下の繰り返し
    • 【5-2】{m,}:直前の1文字のm回以上の繰り返し
  • 〔1〕+?:直前の1文字の1回以上の繰り返し〔ただし最小マッチ〕
  • 〔2〕*?:直前の1文字の0回以上の繰り返し〔ただし最小マッチ〕
  • 〔3〕??:直前の1文字の0回または1回の繰り返し〔ただし最小マッチ〕
  • 〔4〕{n}?:直前の1文字のn回の繰り返し〔ただし最小マッチ〕→?を付けても意味が変わらないで、実際には使われない。
  • 〔5〕{m,n}?:直前の1文字のm回以上、n回以下の繰り返し〔ただし最小マッチ〕
    • 〔5-1〕{,n}?:直前の1文字の0回以上、n回以下の繰り返し〔ただし最小マッチ〕
    • 〔5-2〕{m,}?:直前の1文字のm回以上の繰り返し〔ただし最小マッチ〕

質問を間違えました。以下の二つは挙動が異なる。 (.?)\t{0} (.?)(?!\t) abs def

  

\t{0}の意味: 「タブ文字0回」を示すため、実質的に無効な記述です。 実際の挙動: (.*?)と完全に同一の動作になります(例: “abc"に対して両パターンとも"abc"をキャプチャ)。 注意点: タブ文字の有無に関係なく動作し、

正規表現の検索パターンと検索文字列〔リプレースメント〕を構成する文字種

持([たちつてとっ])

  • プログラム実行中の値のうち、変化しないものを定数〔constant〕といい、変化するものを変数〔variable〕という。
  • 定数の一部をリテラル〔literal〕が占め、残りを**シンボリック定数〔symbolic constant〕**が占める。
    • リテラルは、定数の一部として、プログラム中で値を直接的に表すために使われる。
    • シンボリック定数とは、プログラム中で使う定数〔変更できない値〕に特定の名称を与えることを通じて、コードの可読性や保守性を向上させるための仕組みである。
    • シンボリック定数とは、ユーザの便益のために、ユーザやプログラマによって定義された定数である、といえる。
  • 正規表現でいうリテラルとは、[プログラム中で値を直接的に表すために使われる文字・数字・記号を含む文字列]のことをいう。
  • リテラルは、文字・数値・記号・文字列など、広範なデータ型すべてを含む言い回しである。
  • リテラルに関連する用語を列挙する。
    • 文字リテラル〔character literal〕:リテラルのうち、とくに文字という単位に限定した言い回し
    • リテラル文字〔literal character〕:メタ文字〔metacharacter〕との対比で用いる強調表現
  • 正規表現の構成要素は、メタ文字とリテラル文字とに大別される。
    • メタ文字〔metacharacter〕〔例:.*+?^$など〕
    • リテラル文字〔literal character〕〔例:a、1、@など〕
  • エスケープ処理の仕様について:
    • メタ文字をリテラル文字として扱うために、メタ文字の前に\`といったエスケープ文字〔escape character〕を付けて用いる。
      • AutoHotkey 2.0の正規表現では、検索パターン中では\がエスケープ文字として使われる一方で、置換文字列においては、**バッククォート(`)**がエスケープ文字として使われる仕様となっており、たとえば `r`n によってWindowsの改行コードを表現できる。
    • \.\*\+\?\^\$\(\)\{\}\|\[\]\\ など、メタ文字にエスケープを施したものを[エスケープされたリテラル〔escaped literal〕]という。
    • エスケープシーケンス〔escape sequence〕とは、エスケープ文字〔escape character〕〔例:\` など〕で始まる一連の文字列パターンであり、次の三つの機能を実現する目的をもつ。
      1. 制御コードの生成〔例:\r\n\n\t など〕
      2. メタ文字の無効化〔エスケープされたリテラルを作る|例:\+\.など〕
      3. 抽象的文字表現〔コード番号による文字表現|例:\x41\u3042など〕
  • 正規表現におけるエスケープされたリテラルの取り扱いについて:
    • [エスケープされたリテラル]は、正規表現中で特別な意味をもつ文字〔メタ文字〕を文字通りに扱うためのエスケープシーケンスの一種である。
    • 【1】量指定子〔{n}?など〕が[直前の1文字]に適用されるという文脈において、正規表現のパターン中に\.\x41\u3042などのエスケープシーケンスが含まれている場合、それぞれは1文字の文字リテラルとして評価され、量指定子はその1文字に適用される〔ただし、\u3042のような Unicode エスケープの扱いは正規表現エンジンによって異なり、たとえば AutoHotkey では\x{3042}のような形式が必要となる〕。
      • 例えば、\r\nは2つの制御文字から成るエスケープシーケンスであり、正規表現エンジンでも2文字として扱われる点に注意が必要である。
    • 【2】文字クラスで指定された文字の[いずれか1文字]にマッチするという文脈において、正規表現の文字クラス〔[ ]〕内に\.\x41\u3042などのエスケープシーケンスが含まれている場合でも、それぞれは1文字のリテラルとして扱われ、指定された文字のいずれか1文字にマッチするというルールが適用される〔ただし、Unicode エスケープの扱いはエンジンによって異なる。AutoHotkey では\x{3042}の形式を使用する必要がある〕。
      • 文字クラスは、角括弧[]で囲まれた文字の集合を定義する正規表現の構文要素であり、集合内に含まれるいずれか1文字にマッチする。
    • 【3】後方参照における一致対象の長さ判定において、キャプチャグループ内に含まれるエスケープされたリテラルは1文字として扱われるため、後方参照〔例:\1,`$1〕との一致確認も1文字単位で行われる。
      • 例えば、(\x41)\1(\x41)$1"AA"にマッチする。ここで\x41は “A” を表す1文字であり、\1も “A” と一致している。
    • 【4】一致範囲〔マッチ長〕の計算においても、エスケープされたリテラルは1文字としてカウントされる。
      • 例えば、abc\x41に対して"abcA"がマッチした場合、マッチ長は4であり、\x41は1文字として扱われる。
    • [エスケープされたリテラル]が1文字として扱われる点を特に意識する必要があるのは、上記の【1】量指定子の対象、【2】文字クラス内でのマッチ対象、【3】後方参照との一致評価、【4】マッチ範囲の計算といったケースである。

正規表現のメタ文字一覧

メタ文字・シーケンス 英訳 説明
* Asterisk 直前の文字の0回以上繰り返し
+ Plus Sign 直前の文字の1回以上繰り返し
? Question Mark 直前の文字が0回または1回出現
$ Dollar Sign 文字列の末尾〔行末にもマッチ〕
^ Caret 文字列の先頭/文字クラス内では否定を表す
. Dot 任意の1文字〔改行を除く〕
() Parentheses グループ化/キャプチャ
| Pipe 代替〔a|bは a または b〕
\ Backslash メタ文字のエスケープ、特殊シーケンスの導入
{} Curly Braces 繰り返し回数指定〔{m}{m,n}
[] Square Brackets 文字クラス〔任意の1文字〕
\d Digit 数字〔[0-9]と等価〕
\w Word Character 単語構成文字〔ASCIIでは[a-zA-Z0-9_]
Unicode対応環境では拡張される〕
\s Whitespace 空白文字〔スペース、タブ、改行など〕
\b Word Boundary 単語の境界〔単語文字と非単語文字の間〕
\t Tab 水平タブ〔制御文字〕
\n Line Feed 改行〔Unix系:Linux、 macOSなど〕。
制御文字でありメタ文字ではない
\r Carriage Return キャリッジリターン〔Mac OS 9以前など〕。
制御文字でありメタ文字ではない
\r\n CR + LF Windowsの改行コード。
2文字の並びであり、1つのメタ文字ではない
\z End of String 文字列の絶対的末尾。$との違いに注意
\uXXXX Unicode Escape Unicode文字指定〔例:\u0041で 'A'〕。
※AutoHotkeyでは\x{3042}を使用
\xXX Hexadecimal Escape 16進数による文字指定〔例:\x41で 'A'〕
\p{...} Unicode Property Unicodeプロパティに基づく文字クラス
〔例:\p{Hiragana}
\P{...} Negated Unicode Property Unicodeプロパティの否定
〔例:\P{Hiragana}はひらがな以外〕
(?:...) Non-Capturing Group グループ化するがキャプチャしない
(?=...) Positive Lookahead 指定条件が後に続く場合にマッチ〔先読み〕
(?!...) Negative Lookahead 指定条件が後に続かない場合にマッチ〔否定先読み〕
(?<=...) Positive Lookbehind 指定条件が前にある場合にマッチ〔後読み〕
(? Negative Lookbehind 指定条件が前にない場合にマッチ〔否定後読み〕

文字クラス〔パターンの中で[]とで囲われた領域〕の中での挙動が例外的なメタ文字

メタ文字 説明
^ クラスの先頭でのみ否定機能として機能。それ以外ではリテラル [^abc] → 'a'、'b'、'c'のいずれの文字でもない1文字
[a^b] → 'a', '^', 'b'
- クラス内で-の両隣りに文字やエスケープシーケンスがある場合は範囲指定子として扱われる。それ以外ではリテラル [a-z] → a~z / [-az] → '-', 'a', 'z'
] クラス内の先頭や直後を除き、リテラルとして使うにはエスケープが必要 []a] → ']', 'a' / [\]] → ']'
[ リテラルとして使うにはエスケープが必要 [\[] → '['
\ エスケープ文字として機能。特殊シーケンスや記号のリテラル化に使用 [\^] → '^' / [\\] → '\'
. リテラルのドットとして扱われる [.] → '.'
* リテラルのアスタリスクとして扱われる [*] → '*'
\b クラス内では単語境界ではなくバックスペース(U+0008)として扱われる [\b] → バックスペース
\d, \w, \s クラス内でも使用可能な特殊シーケンス(正規表現エンジンによる) [\d\s] → 数字または空白文字
  • [^abc]の意味については、二つの言い回しで表現することができる。いずれも同じ内容を別の表現で表している。
    • [‘a’以外かつ’b’以外かつ’c’以外である1文字]
    • [‘a’、‘b’、‘c’のいずれの文字でもない1文字]

正規表現のルール

  • ターゲット〔対象〕とするデータの中から、あらかじめ定義された適合条件式〔Matching Condition Expression〕を満たすデータ自体、またはその位置を検出する技術を、パターンマッチング〔pattern matching〕という。
    • 【和訳】:適合条件式とは、文字列が適合したとみなされるために満たす必要があるルールを記述する〔ものである〕。
    • 【英訳】:A Matching Condition Expression describes the rules a string must satisfy to be considered a match.
  • この適合条件式が、一般に単に『パターン』とよばれているものである。 パターンマッチングの対象には、文字列、数値、画像などがある。 これらのうち正規表現〔regular expression〕は、とくに文字列に対するパターンマッチングを目的とした適合条件式を記述するための表記法の一つである。

マッチする〔to match〕とは

  • 正規表現の説明において[マッチする〔to match〕][マッチ〔a match〕]という意味で[一致する][一致]という言葉を使うのは不正確であり誤解を生みやすい。 なぜならば、日常生活で使う[一致]という言葉には[完全に同じ]という意味が含まれているからである。
    • [完全に同じ]ということは、[解が一つであること]つまり[同一性]を暗示しており、そうだとすれば正規表現のパターンには、[変化の幅〔変域〕を容認する因子をもたない固定値]だけをもつことが想定される。
    • そうだとすれば、正規表現を用いたパターンマッチング・検索・置換を行なう意味がない。
    • そうだとすれば、固定値を用いた通常のパターンマッチング・検索・置換を行なえばよいのである。
    • 正規表現を用いてパターンマッチング・検索・置換を行なうさいは、次のような[変数要素]をパターンに含めるのが一般的である。

正規表現を用いてパターンマッチング・検索・置換を行なうさいの[変数要素]を漏れなく列挙してください。

    - 【1】`.`による任意文字指定
    - 【2】`\d`による数字限定指定
    - 【3】論理和指定子〔alternation〕と名付けられた`|`による選択的指定〔例:`A|B`→'A'または'B'〕
    - 【4】範囲指定子〔range specifier〕と名付けられた`-`による範囲指定


    - 【1】`.`による任意文字指定
        - `.`は改行コード〔`\r\n`・`\n`・`\r`〕を除くあらゆる1文字にマッチ〔数字・記号を含む〕
        - `.`で改行を含めるにはシングルラインモード〔`/s`修飾子〕が必要
    - 【2】`\d`による数字限定指定
        - `0-9`の半角数字のみに厳密対応〔全角数字は別途`[0-9]`が必要〕
    - 【3】論理和指定子〔alternation〕と名付けられた`|`による選択的指定〔例:`A|B`→'A'または'B'〕
        - 選択パターンをグループ化するためには`(A|B)`のように括弧が必要
        - 例:`(cat|dog)`は[catまたはdog]にマッチ
    - 【4】範囲指定子〔range specifier〕と名付けられた`-`による範囲指定
        - 文字クラス内〔`[`と`]`で囲われた範囲〕において、`-`の両隣りに文字やエスケープシーケンスが存在する場合に限り、`-`は範囲指定子〔range specifier〕として扱われる。
        - それ以外の位置〔文字クラスの先頭や末尾、または`-`単独で使われる場合など〕では、`-`はリテラルのハイフン(-)として扱われる。
        - 文字クラスの外では、`-`は常にリテラルのハイフン(-)である。

        - 範囲指定子`-`による範囲指定は、角括弧`[`と`]`とで囲まれた文字の集合である[文字クラス]の内部で`-`の両隣りに文字がある場合においてのみ行なわれる。〔例:`[a-z]` → a~z 〕
        - [文字クラス]の内部であっても、`-`の両隣りに文字がなければ`-`が範囲指定子として機能することはなく、単なるリテラルの'-'として取り扱われる。〔例:`[-az]` → '-', 'a', 'z'〕
         - 文字コード順で範囲を定義(例:`[A-Za-z]`で全英字)
         - よく使われる[文字クラスの中で範囲指定子を使った文字種指定]の例
            - 英小文字半角:`[a-z]`
            - 英小文字半角以外〔大文字・非英字など〕:`[^a-z]`
            - 英大文字半角:`[A-Z]`
            - 英大文字半角以外〔小文字・非英字など〕:`[^A-Z]`
            - 英数半角〔英字+数字〕:`[a-zA-Z0-9]`
            - 英数半角以外〔記号・全角文字など〕:`[^a-zA-Z0-9]`

量指定子

文脈

文字クラスは、角括弧[]とで囲まれた文字の集合を定義する正規表現の要素で、文字クラスで指定された文字のいずれか1文字にマッチする機能をもつ。

角括弧で囲んだ文字のリストを作成し、その中のどれか1文字にマッチします

2025-05-02 4:41

以前の範囲指定子-にかんする回答において、[文字リテラル]と[文字コード]を直接結合可能とあなたは回答した。 それは\x{4E9C}-熙などが可能という意味なのか?

    - 【4】`-`による範囲指定

    
        - 文字クラス内で[Unicodeコードポイント順]を活用
        - 例:`[あ-ん]`で平仮名全範囲を効率的に網羅

|:論理和指定子〔alternation〕]

  • 英字半角〔大文字小文字を含む〕:a-z|A-Zまたは[a-zA-Z]

  • 英字半角以外〔非英字・全角文字など〕: [^a-zA-Z]と等価の正規表現の別表現を知りたい。 以下を修正してほしい。 (?:^a-z|A-Z)

      で一括的にパターンマッチング・検索・置換を行なうことができる。
    
      や
    

|が論理和指定子〔Alternation〕なら は何ですか

論理和指定子(Alternation) (OR) 正規表現のパターンにおいて、文字どうしをOR演算子|で結んだ指定を、[論理和的指定]と名付けることは適切か?

広義の文字の文字コードの並び順を背景にして、始点文字と終点文字とを- 変域指定 によって、[広義の文字]の中でも、とくに数字〔0から9〕だけを指定する。

    or
- つまり【1】【2】のような[変化の幅〔変域〕を容認する因子]をパターンの中に含めて指定するのがふつうである。

123 任意の数字

量指定子
固定値であり
- ところが、正規表現で使われるパターンにマッチする文字列は、多種多様であり、そのありさまは、[一致する]が暗示している[解が一つである]こととは、ほど遠い。
- つまり[マッチ]と[一致]は明らかに異なる状態・現象を意味している、といえる。
  • 適合条件式を正規表現で記述した結果、対象となる文字列において発生する[マッチする〔to match〕]という現象は、[条件に適合する]〔to match the conditions〕と言い換えることができる。
  • 正規表現でいう[マッチする]とは、条件に適合する〔to match the conditions〕ということであり、それは[一致する]という日本語がもつ[完全に同じ]という意味・含意とは異なる。
  • [一致する]という日本語は、[完全に同一である]、つまり[解の一意性]を含意している。
  • この意味での「一致する」を英語で表現する場合、厳密には次の表現が最適だとされる:
  • 技術文書:“be identical to"が最も普遍的
    • “be identical to”
    • (文字列/構造/内容が完全に同一であることを強調)
    • → 例:“The input string is identical to the reference pattern.":入力文字列は参照パターンと同一である。
  • プログラミング:“exactly equivalent to"が実装の正確性を伝える
    • “exactly equivalent to”
    • (数学的/論理的な同値性を強調) The generated code is exactly equivalent to the specification.
  • 学術論文:“perfectly coincide with"で厳密性を表現
    • “perfectly coincide with”
    • (概念/値/構造が寸分の違いなく重なるニュアンス)
    • → 例:“The result perfectly coincides with the expected format.":結果は期待された形式と完全に一致している。
  • ビジネス文書:“precisely correspond to"が好まれる
    • “precisely correspond to”
    • (定義された基準との1:1対応関係を厳密に表現)
    • → 例:“The output precisely corresponds to the predefined template.":出力は事前定義されたテンプレートに正確に対応する。
  • [完全一致]とは、[比較対象の全要素が、寸分たがわず同一であること]を意味する。
  • 正規表現を使って^ABC$〔行頭^・行末指定$〕を使うと、[“ABC"だけで構成される行]にマッチし、このような場合には[完全なるリテラルマッチ]が発生し、これは文字通り[完全一致]である。けれども、これは特殊かつ稀なケースである。
  • ただし仮に[曖昧な要素]〔.*など〕がパターン内に含まれている場合〔^pattern.*$〕、[一致する]という日本語が含意している[解の一意性]は失われる。
    • 【例1】:真の[完全一致]:^ABCDE$→ “ABCDE"のみにマッチ。
    • 【例2】:疑似[完全一致]:^A.*E$→ “AE”、“AXYE”、“AdadadaE”、“AsomethingE"など、幅広い範囲にマッチ。
  • そもそも正規表現とは、適合条件式つまりパターンに[曖昧な要素]〔.*など〕をもたせることを通じて、マッチする対象を広くとることにより、パターンマッチング・検索・置換の効率を高めることを目的としている部分が大きい。
  • つまり正規表現を利用するそもそもの趣旨が、[複数解を許容する]ことにあるわけである。
  • したがって、正規表現という文脈において、真の[完全一致]という現象が起こるのは、[完全なるリテラルマッチ]が発生する、特殊かつ稀なケースにおいてのみであり、それは無視できる些末な問題だといえる。
  • そういう性格をもつ[正規表現]だというのに、

正規表現の世界で、マッチを一致と言い換えている用語として、どのようなものがあるか? 完全一致 最長一致 最短一致

はそういった一部の例外を除き、複数解を許容する という文脈は、 「マッチ」→「適合/条件充足」 (複数解を許容する文脈)

  • [完全一致]つまり[解の一意性]を求めるのであれば、正規表現によるパターンマッチング・検索・置換ではなく、通常表現によるパターンマッチング・検索・置換を行なえばよいのである。

  • 正規表現を使う場合には、以下のパターンのような、マッチする対象が幅広いパターンを使うのが普通である。

    • .*〔任意の文字(改行除く)が0回以上連続する〕
      • 例:a.*z→ “az”, “abz”, “abcdefgz” にマッチ
    • .*?〔非貪欲(最小一致)の任意文字列〕
      • 最短マッチを優先(例:a.*?zで “axbzc” → “axbz” のみ抽出)
    • .+〔任意の文字(改行除く)が1回以上連続する〕
      • 例:a.+z → “abz” にマッチ(“az” は非マッチ)
    • .+?〔非貪欲(最小一致)の1文字以上〕
      • 最短マッチ優先(例:a.+?z で “abzbzc” → “abz” のみ抽出)
    • \d+〔半角数字が1回以上連続する〕
      • 例:\d+ → “123”, “0”, “987654” にマッチ
    • \d+?〔非貪欲な半角数字の1回以上〕
      • 最短数字列を優先(例:\d+? で “123” → “1”, “2”, “3” を個別に認識)

半角

.*? .+ .+? \d+ \d+?

にもマッチ〔厳密には完全一致ではない〕
  • この区別を明確にするため、[完全一致]は[パターンとの同一性]ではなく[データの完全同一性]を指す表現として再定義する必要がある。

  • 例えば、[a-zA-Z]{1,8}という正規表現は、1文字以上8文字以下の連続する英字半角〔半角英字〕のすべてにマッチする。

  • このとき、[マッチする]を[一致する]と言い換えるのはおかしい。

  • 正規表現が

小文字/大文字のアルファベットにマッチする正規表現 マッチ 最短一致・最長一致のほかに、訳語は、

後方 一致

  • それは[一致]という言葉には[完全に同じ]という意味が含まれているからである。
  • [マッチする〔to match〕]とは、[条件に適合する]という意味である。

のことを指し示す意味で

適合する

マッチ〔to match〕とは、検索・置換において設定した条件であるパターン [パターンに当てはまること][パターンが示す条件に該当/合致すること][パターンが示す条件を満たしていること] をいう。 -

[マッチングルール]およびその他を包括的に整理すると、以下のようになる。

0. 前提となる説明

特徴

  • 正規表現によって[ある特定のパターンをもつ文字列を指定する]と、検索・置換において 指定したパターンを通じて[設定した条件に、ターゲットである

  • ある文字列の中から[連続した一部の文字]を抜き出したものを部分文字列という。

    • 部分文字列は、必ず連続していなければならない。
    • 正規表現の文脈では、[パターンにマッチした文字列]や[キャプチャグループで取得された文字列]を部分文字列とよぶことがある。
  • 正規表現の用語|ターゲット/パターン/リプレースメントについて述べる。

    • 【用語】:ターゲット〔対象〕:正規表現による検索や置換の操作対象となる文字列やファイル全体のこと。
    • 【用語】:パターン〔検索パターン〕:正規表現による検索時・置換時に、ターゲット内でどのような条件を満たす文字列にマッチさせたいかを指定する検索基準のこと。
    • 【用語】:置換文字列〔リプレースメント〕:正規表現による置換時に、マッチした部分をどのような内容に置き換えるかを指定する置換基準のこと。 グループ参照などの特殊な記法を含む場合もある。
  • 例えば、サクラエディタのマクロ〔.mac〕の正規表現置換では、S_ReplaceAll('●●●' , '★★★', 44);のように記述する。

    • このS_ReplaceAll('●●●' , '★★★', 44);という記述のターゲットは、サクラエディタで開いているファイルを構成する文章・コードなどの文字列である。
    • S_ReplaceAll('●●●' , '★★★', 44);の●●●のたぐいを英語では[pattern]といい、[pattern]を[検索パターン]または[パターン]と和訳するのが一般的である。
    • S_ReplaceAll('●●●' , '★★★', 44);の★★★のたぐいを英語では[replacement]または[replacement string]といい、[replacement]も[replacement string]も、[置換文字列]と和訳するのが一般的である。
  • 正規表現を使った置換では、入力文字列またはファイル〔これらをターゲット:targetと総称する〕のうち、正規表現パターン〔regular expression pattern〕にマッチする〔to match〕部分が、置換文字列〔replacement string〕に置き換えられる〔be replaced with〕。

  • それを英訳する。In a regular expression replacement, parts of the input string or file (the target) that match the regular expression pattern are replaced with the replacement string.

  • パターンは左から右へ記述される。

    • パターンの[最初][先頭]とは、パターンの最も左を意味する。
    • パターンの[最後][末尾]とは、パターンの最も右を意味する。
  • パターンにおいて記述順序が重要視されるのは、検索・置換において、パターンの記述順序が、マッチングが行なわれる順序にそのままなるからである。

    • [検索・置換において、どのような順番でマッチングさせたいか]を念頭に置きながら、パターンの記述順序を決める必要がある。

マッチングルールについて、誤り・過不足があれば修正してください。

1. マッチングルール

  • たいていの正規表現エンジンのデフォルト動作は、最長マッチ〔longest match〕貪欲マッチ〔greedy match〕である。 最長マッチ 貪欲マッチ
  • 複数の部分文字列がマッチする場合、最も先頭にある部分文字列が優先して返される。
  • 同じ開始位置で複数の部分文字列がマッチする場合、欲張り〔グリーディ〕なら最長、非欲張り〔非グリーディ〕なら最短というように、**量指定子の属性〔欲張り/非欲張り〕**によって返される文字列が変わる。
  • マッチングには[完全一致][部分マッチ][先頭マッチ][末尾マッチ]などがある。
  • .は任意の1文字〔改行以外〕にマッチする。
  • \dは任意の半角数字にマッチする。
  • 文字クラス〔[abc]など〕やエスケープ〔\.など〕による細かなマッチ指定ができる。

1.マッチングルール

  • 同じ開始位置で複数の部分文字列がマッチする場合、量指定子の属性〔欲張り(グリーディ)/非欲張り(非グリーディ)〕によって返される文字列が変わる。欲張りなら最長、非欲張りなら最短となる。

    • 正規表現において、?をつかって[最短マッチ]を宣言しないかぎり、正規表現では欲張り(グリーディ)な指定が自動的に選択される。
      • 要は[正規表現で量指定子〔*, +, {n,m} など〕 [最長マッチ]
  • 量指定子はデフォルトで[最長マッチ〔グリーディ〕]、*?+?のように[最短マッチ〔非グリーディ〕]にできる。

    • ?を他の量指定子〔*, +, {n,m} など〕 と組み合わせて使うと[最短マッチ]を表す。

?を他

  • *?:直前のパターンが0回以上、できるだけ短くマッチ
    • <a.*?><aから>までの最短の部分にマッチし、このとき<aの直後に文字があってもなくてもよい。
    • <a.*?>About</a><a>About</a><a href="https://oooo.ooo/" target="_blank" rel="nofollow">About</a>などにマッチする。
  • +?:直前のパターンが1回以上、できるだけ短くマッチする。
    • 関係.+?詞は、関係詞にはマッチせず、関係代名詞関係副詞にマッチする。
  • {n,m}?:直前のパターンがn回以上m回以下、できるだけ短くマッチする。
    • a.{2,5}?bは、aとbの間に2文字以上5文字以下が入る最短の部分にマッチする。
    • a.{3,}?bは、aとbの間の3文字以上のうち、最短の部分にマッチする。
    • a.{,4}?bは、aとbの間の0~4文字のうち、最短の部分にマッチする。
量指定子(最長一致) 最短一致 意味
* *? 0回以上の繰り返し(最短一致)
+ +? 1回以上の繰り返し(最短一致)
? ?? 0回または1回の繰り返し(最短一致)
{n,m} {n,m}? n回以上m回以下の繰り返し(最短一致)
  • 例えば(.*?)? ? で最短マッチを指定しないかぎり、最長マッチに自動的になる、という意味か? 

複数の部分文字列がマッチする場合、最も先頭にある部分文字列が優先して返される(左端最長一致)。 「左端最長一致」という用語は、最も先頭にある、かつ最長の部分文字列を返すことを指します(多くの正規表現エンジンのデフォルト動作)。

  • マッチングには[完全マッチ][部分マッチ][先頭マッチ][末尾マッチ]などがある。
    • 完全マッチ:文字列全体がパターンに適合する場合
    • 部分マッチ:文字列の一部がパターンに適合する場合
    • 先頭マッチ:文字列の先頭がパターンに適合する場合〔^
    • 末尾マッチ:文字列の末尾がパターンに適合する場合〔$
  • .は任意の1文字〔改行を除く〕にマッチする。 ※一部の正規表現エンジンではフラグ〔例:sDOTALL〕によって改行にもマッチする場合がある。
  • \dは任意の数字〔通常は半角数字0-9〕にマッチする。 ※Unicode対応の正規表現エンジンでは全角数字や他の数字にもマッチする場合がある。
  • 文字クラス〔例:[abc]〕やエスケープ〔例:\.〕による細かなマッチ指定ができる。

補足

-[左端最長一致]という用語は、最も先頭にある、かつ最長の部分文字列を返すことを指します〔多くの正規表現エンジンのデフォルト動作〕。

  • 正規表現エンジンや使用する言語によって挙動や対応範囲が異なる場合があります。

ご参考までに、修正後の内容をまとめて記載しました。ご活用ください。

PerplexityのEliotより:https://www.perplexity.ai/search/zheng-gui-biao-xian-noruruniha-BImdtEhUTF6Yu6l1L962mA?utm_source=copy_output

量指定子の?と最短マッチの?とが重なる例はあるか?

2. 記法・構文ルール

  • [基本正規表現〔BRE〕]と[拡張正規表現〔ERE〕]など、記法の違いによるルールが存在し、使えるメタ文字や構文が異なる。
  • 例:+?は拡張正規表現でのみ使える場合がある。

3. 繰り返し・量指定子のルール

  • *〔0回以上〕、+〔1回以上〕、?〔0回または1回〕、{n,m}〔n回以上m回以下〕など、繰り返しの指定方法に関するルール。

4. 否定・除外のルール

  • [^...] のように、特定の文字やパターンを[含まない]ことを表現する除外のルール。
  • 先読み否定〔Negative Lookahead〕などを使い、[特定の文字列を含まない行]なども表現できる。

5. 最長マッチ・最短マッチのルール

  • 量指定子はデフォルトで[最長マッチ〔グリーディ〕]、*?+?のように[最短マッチ〔非グリーディ〕]にできる。

6. グループ化・参照のルール

  • ()でパターンをグループ化し、後方参照〔\1, \2など〕で同じ部分を再利用するルール。

7. 文字クラス・POSIXクラスのルール

  • [abc]のような文字クラスや、[[:digit:]]〔数字〕、[[:alpha:]]〔アルファベット〕などPOSIXクラスを使ったルール。

8. 行頭・行末・単語境界のルール

  • ^〔行頭〕、$〔行末〕、\b〔単語境界〕など、文字列の位置に関するルール。

9. フラグ・オプションのルール

  • グローバル検索〔g〕、大文字小文字無視〔i〕、複数行〔m〕など、フラグによる動作変更が可能。

10. エスケープのルール

  • メタ文字を通常の文字として扱いたい場合はバックスラッシュ\でエスケープする。

まとめ

正規表現のルールには[マッチングルール]だけでなく、構文・記法の違い、繰り返しや否定、最長・最短マッチ、グループ化や参照、文字クラス、位置指定、フラグ指定、エスケープなど多様なルールが含まれています。これらを組み合わせることで、複雑な文字列処理が可能になります。

●●●工事中●●●

正規表現のルールには、マッチングルール以外に何があるか? とパターン

以下をコンパクトに凝縮してください。

正規表現の[式]と[構文]の違い

正規表現の[式]

正規表現の[式]とは、特定の文字列パターンやマッチングルールを表現するための記号列のことです。 具体的には、検索対象〔ターゲット〕の文字列がどのような形式や条件に一致するかを示すものです。 正規表現式自体は、テキスト検索や置換処理などで利用される具体的なパターンを定義するために使われます。 たとえば、^a.*b$や\d{3}-\d{2}-\d{4}などが、正規表現式の例です。

正規表現の[構文]

正規表現の[構文]とは、正規表現式を構成するために使用されるメタ文字や演算子、そしてその使い方に関する体系的なルールのことを指します。 つまり、正規表現を正しく記述するための文法に相当します。 これには、文字クラス〔例:\d〕、繰り返し (repetition) を表す量指定子〔例:+や*〕、グルーピング〔例:()〕など、正規表現の各要素がどのように組み合わさるかに関する規則が含まれます。

実例1\d{3}-\d{4} → 郵便番号の形式(3桁数字+ハイフン+4桁数字)
実例2[a-zA-Z]{5}大文字・小文字アルファベットが5文字連続した文字列(例: Stand, desks, Piano
実例3明日は[晴曇雨]です → 「明日は晴です」「明日は曇です」「明日は雨です」にマッチ

正規表現の構文とは、ルール体系

正規表現の[構文]は、式を構成するためのメタ文字や演算子の体系的なルールつまり[文法]を意味する。 実例1〔量指定子〕:*〔0回以上〕、+〔1回以上〕、{n}〔n回繰り返し〕 例:a* → “a"が0回以上連続〔空文字列や"a”, “aa"にマッチ〕 実例2〔文字クラス〕:[]内のいずれか1文字にマッチ 例:[あいうえお] → “あ”、“い”、“う”、“え”、“お"のいずれか 実例3〔グループ化〕:〔〕で囲んだ部分を1つの単位として扱う 例:〔ab〕+ → “ab"の1回以上繰り返し〔“ab”, “abab"にマッチ〕

正規表現の[式〔パターン〕]と[構文〔ルール〕]の違い

特定の文字列パターンとマッチングルールの関係性 本質的な違い 文字列パターン 具体的なマッチ対象(例: \d{3}-\d{4}は「3桁数字+ハイフン+4桁数字」というパターン) 正規表現の「式」に相当(検索対象の形式を直接表現した記号列) マッチングルール パターンを解釈するための仕組み(例: は「0回以上」、()は「グループ化」) 正規表現の「構文」に相当(メタ文字や演算子の動作ルール) 具体例で見る関係性 同一視できないケース: パターン: .?(最短一致) ルール: ?は「0回以上の繰り返し(最短優先)」という動作規則 → パターンはルールの具体化(?というルールを使って.?というパターンを構成) 実用上の同一視: 文脈によって「郵便番号のパターン(\d{3}-\d{4})」を「マッチングルール」と呼ぶ場合もあるが、厳密にはパターンはルールの適用結果 結論 技術的定義: 異なる概念(パターン=式/ルール=構文) 実務上: 「パターン」を「ルール」の一部として扱うケースも存在するが、厳密には区別が必要 例外的ケース: 最短一致(?)やキャプチャ((?: ))など、ルールがパターンの挙動を直接規定する

正規表現の[式]

正規表現の[式]とは、

特定の文字列パターンやマッチングルールを表現する記号列〔例:^a.*b$, \d{3}-\d{2}-\d{4}〕。検索・置換処理で直接使用される具体的なパターン定義。

正規表現の[構文]

正規表現の[構文]とは、式を構成するメタ文字・演算子の体系的なルール〔例:\d(数字〕, +〔1回以上〕, 〔〕〔グループ化〕)。正規表現を記述するための文法。 差の本質:式=パターン実体, 構文=ルール体系。

PerplexityのEliotより:https://www.perplexity.ai/search/zheng-gui-biao-xian-noshi-gou-KFIIpFGrRnm1vPICD7Mi0A?utm_source=copy_output

正規表現の式とは、パターンそのもの

以下を修正・補足してください。 正規表現の式と構文の違い 正規表現の[式]は、文字列のパターン、いいかえれば、マッチングルールを直接的に表現する記号列を指す。 正規表現の[構文]は、式を構成するためのメタ文字や演算子の体系的なルールつまり[文法]を意味する。

正規表現の改行コードの書き表し方

OS・環境 正規表現 改行コード 16進表記 意味
Windows \r\n CR+LF 0x0D0A CR+LF〔Carriage Return + Line Feed〕
Unix系:Linux、macOS \n LF 0x0A LF〔Line Feed〕
Mac OS 9以前 \r CR 0x0D CR〔Carriage Return〕

正規表現においてエスケープが必要な文字のまとめ

  • エスケープとは、該当する文字の直前に\をつけることで、[該当する文字について、正規表現の機能を果たす意図がない]という宣言を行なうことである。
  • \は、Windows日本語環境では[円マーク]として表示されるけれども、それ以外では[逆スラッシュ]として表示される。

1. [どの正規表現でもエスケープ必須]9つ

  • ^$\()[]{}

2. [特殊な場合にエスケープ]7つ

  • .*+?|-#

3. [ほとんどエスケープ不要]3つ

  • "'/

1. [どの正規表現でもエスケープ必須]

  • ^〔アンカー、行頭〕
  • $〔アンカー、行末〕
  • \〔エスケープ文字それ自身〕
  • (〔グループ化の開始〕
  • )〔グループ化の終了〕
  • [〔文字クラスの開始〕
  • ]〔文字クラスの終了〕
  • {〔量指定子の開始〕
  • }〔量指定子の終了〕

2. [特殊な場合にエスケープ]――リテラル文字として使いたい場合にはエスケープが必要

  • .〔任意の1文字〕
  • *〔量指定子(quantifier)、0回以上〕
  • +〔量指定子、1回以上〕
  • ?〔量指定子、0回または1回〕
  • |〔論理和指定子(alternation)〕
  • -〔文字クラス内の範囲指定〕
  • #〔コメント〕:正規表現エンジンによりエスケープの要・不要が異なる。

3. [ほとんどエスケープ不要]

  • "〔ダブルクオート〕
  • '〔シングルクオート〕
  • /〔スラッシュ〕
    • 正規表現がスラッシュで囲まれている場合〔例えば、/pattern/の形式〕、スラッシュ自体はエスケープする必要になる。その他の場面では基本的にエスケープ不要である。

よく使う

正規表現の式・構文

  • \d〔半角数字1文字〕

  • .〔任意の1文字〕

  • {n,m}〔直前の要素がn文字以上、m文字以下(n, mは半角数字の整数)〕

  • {n}〔直前の要素がn回(nは半角数字の整数)〕

  • *〔量指定子、直前の要素が0回以上〕

  • +〔量指定子、直前の要素が1回以上〕

  • ?〔量指定子、直前の要素が0回または1回〕

  • |〔OR演算子〕

  • (example)〔グループ化あり、かつ、キャプチャあり〕

  • (?:example)〔グループ化あり、かつ、キャプチャなし〕

  • (example)?〔文字列exampleがあり、または無し〕

  • [XY]〔XまたはYが1文字〕

  • [a-z][-az]ではハイフンの意味が異なる

  • (sample)はマッチする部分をキャプチャ(捕捉)する

  • \w〔英単語を構成する文字(半角英数字とアンダースコア)〕

  • [^AB]〔AでもなくBでもない任意の1文字〕

  • *+〔貪欲〕

  • *?+?にすると、最短マッチを返す

  • ^〔行頭〕

  • $〔行末〕

  • \t〔タブ文字〕

  • \n〔改行文字〕

  • \s〔空白文字(スペース、タブ文字、改行文字等)〕

  • ABC|DEF〔文字列ABCまたは文字列DEF〕

  • ^は行頭の意味になったり、[^]で否定の文字クラスの意味になったりする

  • \b〔単語の境界〕

  • (?=example)〔exampleという文字列の直前の位置〕

  • (?&lt;=example)[exampleという文字列の直後の位置]を表す(後読み)

  • (?!example)〔exampleという文字列以外の直前の位置〕

  • (?&lt;!example)[exampleという文字列以外の直後の位置]を表す(否定の後読み)

  • ?*+といった量指定子は()

  • |を使ったOR条件では、各条件内でもメタ文字が使える

  • []内ではメタ文字の種類や使われる位置によって各文字の働きが異なる

  • {n,}{,n}はそれぞれ[直前の文字がn個以上][n個以下]の意味になる

  • \W\S\D\Bはそれぞれ\w\s\d\b

  • 例えば、^(.*?)\t(.*?)$は、[タブを区切りにして、一行が前半と後半に分かれている]という意味である。

    • ^は行頭を意味し、$は行末を意味する。
    • `` Windows標準の改行コードは\r\nであり、 は Windows標準 、macOSとLinuxでは\nが標準、古いmacOSでは\rが標準である。

(\r\n|\n|\r)

(\r\n?|\n)

  • 正規表現において[キャプチャーする〔to capture:つかまえる〕]とは、[()とで囲った検索パターン]〔=キャプチャグループ〕にマッチした文字列を、のちほど再利用するために記憶しておくことを意味する。
    • キャプチャグループにマッチした文字列は、左から順に1番目、2番目…と番号が付き、1番目は$1、2番目は$2などで参照できる〔言語やツールによっては\1\2なども使われる〕。
    • $1$2、あるいは、\1\2などの変数は後方参照〔backreference〕とよばれ、キャプチャした文字列を再利用するさいに使われる。
    • マッチした文字列を再利用するつもりがない場合、より実務的には、(?:...)〔=非キャプチャグループ〕という[グループ化するだけで記憶しておかない構文]を使う。
    • 検索パターン^(.*?)\t(.*?)\t(.*?)\t(.*?)$$1:$3:$4という置換文字列に置換する場合、$1:$3:$4のように番号が飛び飛びになると、参照指定のミスが起こりやすいため、キャプチャーしないグループは、最初からキャプチャーしないでおくためにも使われる。
    • つまり^(.*?)\t(?:.*?)\t(.*?)\t(.*?)$としておけば、置換文字列を$1:$2:$3という連番で指定することができるので、参照指定のミスが起こりにくい。
    • また
  • [検索パターンにマッチした]とき、[キャプチャーする][キャプチャーしない]という選択肢がある。
    • [検索パターンにマッチした]とき、[キャプチャーする]ならば、(...)、つまり、キャプチャグループを使う
    • [検索パターンにマッチした]とき、[キャプチャーしない]ならば、(?:...)、つまり、非キャプチャグループを使う
    • [検索パターンに対して、前置された文字列]の[肯定]という条件付きで[検索パターンにマッチさせる]場合、(?<=...)、つまり、肯定後読みアサーションを用いる。
    • [検索パターンに対して、前置された文字列]の[否定]という条件付きで[検索パターンにマッチさせる]場合、(?<!...)、つまり、否定後読みアサーションを用いる。
    • [検索パターンに対して、後置された文字列]の[肯定]という条件付きで[検索パターンにマッチさせる]場合、(?=...)、つまり、肯定先読みアサーションを用いる。
    • [検索パターンに対して、後置された文字列]の[否定]という条件付きで[検索パターンにマッチさせる]場合、(?!...)、つまり、否定先読みアサーションを用いる。
      • ...の三点は検索パターンを意味することとする。

bregonig.dll with Onigmo

  • エンジンは[中身の仕事人]、DLL〔ダイナミックリンクライブラリ〕は[受付・仲介役]に例えることができる。
  • Onigmoは[正規表現エンジン]である。
  • bregonig.dllは[Onigmoを内部エンジンとして利用している、Perl互換の強力な正規表現機能を提供するためのWindows用DLL]である。

利用可能な正規表現
K.Takata's software: bregonig.dll

正規表現の中で注釈機能を使いたい

  • 【方法】:注釈機能を使うためには、注釈内容〔…〕を[(?#]と[)]とで囲う。
(?#...) // 一般式
(?#ここは無視される|ここに注釈を入れる)

キャプチャグループを作りたい

  • 【方法】:正規表現パターン〔…〕を[(]と[)]とで囲う。
(...) // 一般式
(.*) // 0字以上の任意の文字が最長一致でマッチする
(.*?) // 0字以上の任意の文字が最短一致でマッチする
(.{4}) // 4字の任意の文字にマッチする
(\d+) // 連続した半角数字にマッチする
(\d{4}) // 4字の半角数字にマッチする

非キャプチャグループを作りたい|キャプチャせずにグループ化するだけ

  • 【方法】:正規表現パターン〔…〕を[(?:]と[)]とで囲う
(?:...) // 一般式
(?:.*) // 0字以上の任意の文字が最長一致でマッチする
(?:.*?) // 0字以上の任意の文字が最短一致でマッチする
(?:.{4}) // 4字の任意の文字にマッチする
(?:\d+) // 連続した半角数字にマッチする
(?:\d{4}) // 4字の半角数字にマッチする

名前付きキャプチャグループを作りたい2-1

  • 【方法|名前付きキャプチャグループ】:正規表現パターン〔…〕を[(?]と[)]とで囲う
  • 【方法|名前付きキャプチャグループ】:正規表現パターン〔…〕を[(?’name’]と[)]とで囲う:〔bregonig.dllに特有〕
    • 〔bregonig.dllに特有〕はbregonig.dllに特有の表現形式であることを表す。
  • キャプチャグループの命名規則:[(?]または[(?’name’]における[name]の要件:[a-zA-Z_][a-zA-Z0-9_]* の形式が必要(例:group_1 は有効)
  • (?…)または(?’name’…)のキャプチャを参照するには[\k]〔名前付き後方参照〕を使う。
(?<name>...) // 一般式:キャプチャを参照するには[\k<name>]〔名前付き後方参照〕を使う
(?'name'...) // 一般式:キャプチャを参照するには[\k<name>]〔名前付き後方参照〕を使う
(?<Four_digits_num01>\d{4}) // 4字の半角数字にマッチする:Four_digits_num01という参照名
(?'Four_digits_num01'\d{4}) // 4字の半角数字にマッチする:Four_digits_num01という参照名
\k<Four_digits_num01> // 4字の半角数字にマッチした文字列を後方参照する:Four_digits_num01という参照名

名前付きキャプチャグループを作りたい2-2

先読み〔直後領域判定〕・後読み〔直前領域判定〕の[用語的てれこ状態]の解釈法

  • 先読み〔直後領域判定〕・後読み〔直前領域判定〕は、マッチ位置の直後〔先読み〕/直前〔後読み:あとよみ〕に、指定したパターンが存在するかをその場で判定するゼロ幅アサーションである。
    • 先読みにおいては、[マッチ位置の直後の文字列]=[マッチ位置に対して、後置〔こうち〕された〔直後の〕文字列]に対して、指定したパターンが存在するかをその場で判定する。
    • 後読みにおいては、[マッチ位置の直前の文字列]=[マッチ位置に対して、前置された〔直前〕の文字列]に対して、指定したパターンが存在するかをその場で判定する。
  • 正規表現を自然言語になぞらえて考えれば、先読み〔lookahead:直後領域判定〕・後読み〔lookbehind:直前領域判定〕は、用語の使い方が逆のように感じられるであろう。
    • 【後読み・先読み】:マッチ位置から見た[後〔左側〕読み]なのか、[先〔右側〕読み]なのか。焦点はマッチ位置にある。マッチ位置の主観視点が基準。
    • 【直前・直後】:判定対象の文字列が、マッチ位置の直前なのか、直後なのか。焦点は判定対象の文字列にある。判定対象の文字列がマッチ位置の直前か直後かという俯瞰視点が基準。
  • 自然言語の文法では、前置といえば、基準となる語句の直前に、ある語句が置かれた状態をいい、後置といえば、基準となる語句の直後に、ある語句が置かれた状態をいう。
    • シンタックス、つまり、語順にかんする文法規則を述べる場合には、語順を述べる視点を、常に俯瞰視点にするなど、一定の基準を設けて、用語の策定・用語の定義を行なうことが望ましい。

先読み〔直後領域判定〕・後読み〔直前領域判定〕

  • 【英訳】:Lookahead and lookbehind assertions are called ‘zero-width assertions’ since they validate patterns in a string without character consumption. These assertions verify pattern existence while maintaining the current match position.
  • 【和訳】:先読みアサーションと後読みアサーションは、文字を消費することなく文字列内のパターンを検証するため、[ゼロ幅アサーション]とよばれる。これらのアサーションは、現在のマッチ位置を維持しながらパターンの存在を検証する。
    • [文字を消費しない]とは、アサーションの検査終了後にメモリポインタが必ず元位置に復帰することを意味する。先読みでは右方向、後読みでは左方向への一時的なメモリポインタの移動が発生する。しかし最終的なマッチ位置は維持される。
    • そもそも[文字を消費しない][非消費マッチ]などの言い回しがもつ[消費]という言葉から、部外者・初学者において[メモリ消費]と混同する危険性が高いので、[消費][to consume]という表現・概念は、ここでは持ち出さないほうがよいと私は思う。
    • 先読みアサーションと後読みアサーションの文脈に登場する、[文字を消費しない][非消費マッチ][ゼロ幅マッチ][ゼロ幅アサーション]などのジャーゴンは、同一のことを言葉を違えて描写しているだけであり、かつ、本質的には必要のない用語・概念である。
    • ゼロ幅について。現在のマッチ位置を進めることなく、現在のマッチ位置の直後〔先読みアサーション〕または直前〔後読みアサーション〕に[指定した検索パターン]が存在するかどうかを一時的にスキャンして判定する正規表現の構文〔肯定・否定の前読み/後読みアサーション〕のことを、[ゼロ幅アサーション〔ゼロ幅断言〕]というだけのことである。
    • [文字を消費しない][非消費マッチ][ゼロ幅マッチ][ゼロ幅アサーション]などのジャーゴンは、[アサーションの検査を行なう前にメモリポインタの位置を記憶しておく→アサーションの検査を行ないそれが終了する→記憶しておいた位置にメモリポインタを復帰させる]ことを通じて[マッチ位置を保持する]という舞台裏を見せないようにしてあるだけで、裏ではちゃっかりマッチ位置の後ろ〔先読み〕または前〔後読み〕をスキャンしてあるわけである。
      • このようにして、バックグラウンドでスキャンが行なわれているので、先読み・後読みともに、それだけコンピュータに負荷がかかる。
      • また後読み〔アサーション開始アドレスの左側に対するスキャン〕は[右から左へ]という逆向きにスキャンが行なわれる正規表現エンジンにおいては、やや時間がかかるようだ。
    • 先読みアサーションと後読みアサーションで重要なのは、マッチ位置が保持されている〔進まない〕という点である。そこを押さえれば[消費][ゼロ幅]といった余計な概念は無視してよい。
  • 【英訳】:“Consuming characters” and “advancing the matching position” are intrinsically connected concepts in regex processing. Assertions called lookahead and lookbehind—collectively known as lookaround—evaluate patterns in a string without consuming characters or changing the matching position. These zero-width assertions preserve the position of the search cursor both when checking forward (lookahead) and when checking backward (lookbehind) for the existence of a pattern.
  • 【和訳】:[文字の消費]と[マッチ位置の前進]は、正規表現処理において本質的に関連した概念である。先読み〔lookahead〕と後読み〔lookbehind〕とよばれるアサーション〔総称してlookaround〕は、文字の消費やマッチ位置の変更をせずに文字列内のパターンを評価する。これらのゼロ幅アサーションは、パターンの存在を前方〔lookahead〕で確認する場合と後方〔lookbehind〕で確認する場合の両方において、検索カーソルの位置を保持する。
    • the position of the search cursor〔検索カーソルの位置〕とは、メモリポインタが記憶している[マッチ位置の位置情報]の比喩的な言い換え表現である。

[同じ動作になる場合]は、[通常の検索・置換]であり、

は、互いに別のことである。

直後文字列の判定をともなうターゲット

(?=…)|肯定先読みアサーション〔positive lookahead assertion〕

※先読み〔lookahead〕とは、マッチ位置の直後〔右側〕に特定のパターンが存在するかどうかを判定する〔キャプチャはしない〕ことである。

Windows(?=10|11) // 直後に[10]または[11]があるWindowsにマッチ

→[Windows]の後ろに[10]または[11]がある場合にのみマッチ
※このとき[10]または[11]はキャプチャされない

(?!…)|否定先読みアサーション〔negative lookahead assertion〕

※先読み〔lookahead〕とは、マッチ位置の直後〔右側〕に特定のパターンが存在するかどうかを判定する〔キャプチャはしない〕ことである。

\d{3}(?!円)  // 直後に[円]がこない三桁の半角数字にマッチ

→[100円]の[100]にはマッチせず、[100ドル]の[100]にマッチ
※このとき[円]はキャプチャされない

(?<=…)|肯定後読みアサーション〔positive lookbehind assertion〕:〔bregonig.dllに特有〕

※後読み〔lookbehind〕とは、マッチ位置の直前〔左側〕に特定のパターンが存在するかどうかを判定する〔キャプチャはしない〕ことである。

(?<=【)緊急 // 【を直前にもつ緊急にのみマッチ

→[【緊急]の[緊急]にのみマッチ
※このとき[【]はキャプチャされない

(?<!…)|否定後読みアサーション〔negative lookbehind assertion〕:〔bregonig.dllに特有〕

※後読み〔lookbehind〕とは、マッチ位置の直前〔左側〕に特定のパターンが存在するかどうかを判定する〔キャプチャはしない〕ことである。

(?<!秘密)文書 // [秘密文書]ではない[文書]にマッチ

→[機密文書]にはマッチするが[秘密文書]にはマッチしない
※このとき[秘密]はキャプチャされない

(?>…)|アトミックグループ=バックトラック禁止〔bregonig.dllに特有〕

  • アトミックグループ〔(?>...)〕は、一度マッチが決まると途中でバックトラッキングせず、不可分に扱われるため[atomic〔不可分〕]という名前がついている。
  • このアトミックグループという正規表現構文は[バックトラック禁止]を意味する。
  • アトミックグループ内では、複数の分岐や繰り返しがあっても、最初に成功したマッチ以外は試されない。
  • 通常、正規表現エンジンはマッチした後でも他の組み合わせを試す[バックトラッキング]を行なう一方で、アトミックグループ内ではバックトラッキングは発生しない。
  • アトミックグループは、最初に見つかったパターンのみを試し、ダメならすぐに失敗と見なす。
  • 最短一致〔*?+?〕は、できるだけ短い範囲にマッチさせるもので、アトミックグループとは異なる。混同しないように注意が必要である。

Modifier: (?ims-ims:…)

(?imsx) 孤立オプション

(?)

i: 大文字小文字照合

(?)

m: 複数行(サクラエディタではデフォルトでon)

(?)

s: 単一行 (. が \n にもマッチ)

(?)

x: 拡張形式(空白を無視、# 以降を無視)

(?)

(?imsx-imsx)〔bregonig.dllに特有〕孤立オプション(bregonig.dllではオプションの否定が可能)

(?)

(imsx-imsx:…)〔bregonig.dllに特有〕式オプション

(?)

正規表現における[?]の意味

1. 【注意】リテラルな[?]のマッチ

  • リテラルな?をマッチさせるには\?とエスケープする。
    • *\*
    • +\+
    • .\.
    • ?\?
    • {}\{\}
    • ()\(\)
    • []\[\]
    • ^\^
    • $\$
    • -\-
    • |\|
    • /\/

2. 【拡張構文開始マーカー[?]】:名前付きキャプチャグループ

拡張構文開始マーカー】:[(?…)]は名前付きキャプチャグループの宣言である。[?]はグループ名を指定する特別な構文である。

  • [?]の[?]は拡張構文の開始を表すマーカーである。
  • [?]の[name]は任意の名称を意味し、命名規則:[a-zA-Z_][a-zA-Z0-9_]* の形式が必要(例: group_1 は有効)を満たす必要がある。
  • [(?…)]の[()]はグループ化を意味する基本構文である。
  • 例:(?\d{4})
    • 例:後方参照は[\k]で行なう
  • 例:(?\d{2})
    • 例:後方参照は[\k]で行なう
  • 例:(?\d{2})
    • 例:後方参照は[\k]で行なう

2’. 【拡張構文開始マーカー】:名前付きキャプチャグループ

拡張構文開始マーカー】:[(?’name’…)]は名前付きキャプチャグループの宣言である。[?’name’]はグループ名を指定する特別な構文である。

  • [?’name’]の[?]は拡張構文の開始を表すマーカーである。
  • [?’name’]の[name]は任意の名称を意味し、命名規則:[a-zA-Z_][a-zA-Z0-9_]* の形式が必要(例: group_1 は有効)を満たす必要がある。
  • [(?’name’…)]の[()]はグループ化を意味する基本構文である。
  • 例:(?‘year’\d{4})
    • 例:後方参照は[\k’year’]で行なう
  • 例:(?‘month’\d{2})
    • 例:後方参照は[\k’month’]で行なう
  • 例:(?‘day’\d{2})
    • 例:後方参照は[\k’day’]で行なう

3. 【拡張構文開始マーカー】:非キャプチャグループ

1. 【拡張構文開始マーカー】:[(?:...)]は非キャプチャグループの宣言である。
    - [?:]の[?]は拡張構文の開始を表すマーカーである。
    - [?:]の[:]は非キャプチャ機能の開始を表すマーカーである。
    - 例:[(?:https)]:#[https]にマッチし、かつ、[https]をキャプチャーしない。
  • OKです。
  • 補足:
    • 非キャプチャグループは「グループ化はするが、キャプチャ(番号や名前での参照)はしない」ため、後方参照できません。

4. 【量指定子】? の意味

  • OKです。
  • 補足:
    • ? は「直前の要素の0回または1回の繰り返し」を意味します。
    • ? を他の量指定子(*, +, {n,m} など)と組み合わせて使うと「最短一致」になります(次項参照)。

最短一致マーカー[?]が*, +, {n,m}と組み合わせられた使用例を列挙してください。

  • ? を他の量指定子(*, +, {n,m} など)と組み合わせて使うと「最短一致」になります(次項参照)。
  • *?:直前のパターンが0回以上、できるだけ短くマッチ
    • <a.*?><aから>までの最短の部分にマッチし、このとき<aの直後に文字があってもなくてもよい。
    • <a.*?>About</a><a>About</a><a href="https://oooo.ooo/" target="_blank" rel="nofollow">About</a>などにマッチする。
  • +?:直前のパターンが1回以上、できるだけ短くマッチする。
    • 関係.+?詞は、関係詞にはマッチせず、関係代名詞関係副詞にマッチする。
  • {n,m}?:直前のパターンがn回以上m回以下、できるだけ短くマッチする。
    • a.{2,5}?bは、aとbの間に2文字以上5文字以下が入る最短の部分にマッチする。
    • a.{3,}?bは、aとbの間の3文字以上のうち、最短の部分にマッチする。
    • a.{,4}?bは、aとbの間の0~4文字のうち、最短の部分にマッチする。

5. 【最短一致マーカー[?]】

  • OKです。
  • 補足:
    • 例:`` はHTMLタグのような「最短一致」で括弧内を抽出する場合などに使います。
    • 「貪欲(greedy)」と「怠惰(lazy)」の対比がポイントです。

6. 【拡張構文開始マーカー】:先読み/後読み

  • OKです。
  • 補足:
    • 先読み・後読みは「ゼロ幅アサーション」とも呼ばれ、実際に文字列を消費しません。
    • 一部の古い正規表現エンジン(JavaScriptの古いバージョンなど)では後読みがサポートされていない場合があります。

7. 修飾子の制御

  • OKです。
  • 補足:
    • (?i) などの「インラインフラグ」は、パターン全体または部分的にオプションを切り替えるのに使います。
    • 他にも (?m)(複数行モード)、(?x)(コメント・空白許可モード)などがありますが、必要最小限に留めます。

まとめ

  • 全体的に正確で、過不足ありません。
  • 各項目の「目的」や「注意点」を簡単に補足しました。
  • 利用する言語やエンジンによる違い(特に名前付きキャプチャや後読みのサポート)に注意してください。

ご要望通り、補足の範囲は必要最小限に抑えました。 もし特定の言語や用途に合わせた補足が必要な場合は、さらにご指示ください。

1. 【量指定子】:[.?]は[.{0,1}]と等価であり、任意の1文字にかんして、その有無を問わずマッチする。
    - [.?]の[?]は量指定子〔Quantifier〕として[0回または1回]を意味する。
    - その意味が似ている量指定子の使い方をまとめると以下になる。
        - [.*]は[.{0,}]と等価で、その意味は[任意の1文字について0回以上の繰り返し]である。
        - [.+]は[.{1,}]と等価で、その意味は[任意の1文字について1回以上の繰り返し]である。
        - [.?]は[.{0,1}]と等価で、その意味は[任意の1文字について0回または1回]である。
    - 例:[(?:https?)]:#[http]または[https]にマッチし、かつ、キャプチャーしない。
1. 【最短一致マーカー[?]】:[(.*?)]または[(.+?)]において[?]は、[マッチ範囲を最小化するかたちに〔lazily:怠惰に〕マッチする〔最短一致〕]の意味になる。
    - 例:
1. 【拡張構文開始マーカー】:先読み/後読み
    - この[?]は拡張構文の開始を表すマーカーである。
    - (?=pattern):# 肯定先読みアサーション〔直後にpatternが存在〕
        - [?=]の[?]は拡張構文の開始を表すマーカーである。
        - [?=]の[=]は肯定先読みアサーションの開始を表すマーカーである。
        - 例:Windows(?=10) :# [Windows10]の[Windows]にマッチし、[10]をキャプチャーしない。
    - (?!pattern):# 否定先読みアサーション〔直後にpatternが存在しない〕
        - [?!]の[?]は拡張構文の開始を表すマーカーである。
        - [?!]の[!]は否定先読みアサーションの開始を表すマーカーである。
    - (?<=pattern):# 肯定後読みアサーション〔直前にpatternが存在〕
        - [?<]の[?]は拡張構文の開始を表すマーカーである。
        - [?<]の[<]は肯定後読みアサーションの開始を表すマーカーである。
    - (?<!pattern):# 否定後読みアサーション〔直前にpatternが存在しない〕
        - [?!]の[?]は拡張構文の開始を表すマーカーである。
        - [?!]の[!]は否定後読みアサーションの開始を表すマーカーである。
1. 修飾子の制御
    - (?i)  # 大文字小文字無視(例: (?i)ABC → "abc" もマッチ)
    - (?-i) # オプション無効化
        - 例:(?i)hello(?-i)  # "HELLO" にマッチするが、後続は大文字小文字区別
    - (?s)  # 単一行モード(. が改行にマッチ)




バックトラックの挙動:
.*? と .* のパフォーマンス差は入力サイズが大きいほど顕著

Unicode対応:
\w や . の挙動が文字コード設定(UTF-8/Shift_JIS)で変化

エスケープの必要性:

最終結論: ? は文脈によって全く異なる機能をもちます。特に拡張構文((? で始まる)と量指定子の区別が重要です。 正規表現の可読性向上には、コメント付きの(?x)モード活用が有効です。

量指定子の?と最短マッチの?とが重なる例はあるか?

量指定子(最長一致) 最短一致 意味 ? 0回以上の繰り返し(最短一致) + +? 1回以上の繰り返し(最短一致) ? ?? 0回または1回の繰り返し(最短一致) {n,m} {n,m}? n回以上m回以下の繰り返し(最短一致)