← 返回 Day 26 正文

Day 26 · 图解

Day 026 — 图解:字符串高级

本目录包含 Day 026 主题相关的 ASCII 图和 Mermaid 图解。


正则表达式执行流程

NFA 引擎匹配过程

正则: a(b|c)d
文本: "abd"

引擎执行路径:

Step 1: a   → 匹配 'a' ✅
              ↓
Step 2: (b|c) → 分支1: 尝试 'b' → 'b' 匹配 ✅ 选择 b
                   ↓
Step 3: d     → 匹配 'd' ✅
                   ↓
              匹配成功!

如果在分支1失败,回溯到分支2尝试 'c'。
这就是正则引擎的"回溯"机制。

贪婪 vs 非贪婪匹配路径

文本: "<div>a</div><div>b</div>"

贪婪模式: <div>(.*)</div>
  <div>a</div><div>b</div>
  ^^^^^                      → 匹配 <div>
       ^^^^^^^^^^^^^^^^^^    → .* 尽可能多匹配(贪心)
                           ^^^^^^^ → 匹配最后的 </div>
  结果: "a</div><div>b"

非贪婪模式: <div>(.*?)</div>
  <div>a</div><div>b</div>
  ^^^^^                      → 匹配 <div>
       ^                    → .*? 尽可能少匹配(找到一个就停)
        ^^^^^^              → 匹配 </div>
  结果: "a"
  (继续搜索...)

字符编码转换流程

Python 的 str ↔ bytes 模型

┌─────────────────────────────────────────────────┐
│                   内存 (RAM)                      │
│                                                   │
│   str = "你好世界"                                │
│   (Unicode 码点序列: U+4F60, U+597D, U+4E16, U+754C)│
└──────────────────────┬──────────────────────────┘
                       │
          ┌────────────┴────────────┐
          │  str.encode('utf-8')    │
          │  bytes.decode('utf-8')  │
          └────────────┬────────────┘
                       │
┌──────────────────────▼──────────────────────────┐
│                   磁盘/网络                        │
│                                                   │
│   bytes = b'\xe4\xbd\xa0\xe5\xa5\xbd...'         │
│   (UTF-8 编码后的原始字节)                         │
└─────────────────────────────────────────────────┘

UTF-8 编码示意

字符:   A       中       😊
码点:   U+0041  U+4E2D  U+1F60A
二进制: 1000001  100111000101101  11111011000001010

UTF-8 编码:

A (1字节, 0x00-0x7F):
  0xxxxxxx
  01000001  →  0x41

中 (3字节, 0x0800-0xFFFF):
  1110xxxx  10xxxxxx  10xxxxxx
  11100100  10111000  10101101  →  0xE4 0xB8 0xAD

😊 (4字节, 0x10000-0x10FFFF):
  11110xxx  10xxxxxx  10xxxxxx  10xxxxxx
  11110000  10011111  10011000  10001010  →  0xF0 0x9F 0x98 0x8A

Mermaid 图解(渲染后可见)

正则匹配流程

flowchart LR A["输入字符串<br/>abc123def456"] --> B["正则引擎"] B --> C{"尝试匹配<br/>r'\d+'"} C -->|"位置0: 'a'<br/>不是数字"| D["前进到位置1"] D -->|"位置1: 'b'<br/>不是数字"| E["前进到位置2"] E -->|"位置2: 'c'<br/>不是数字"| F["前进到位置3"] F -->|"位置3: '1' ✅<br/>位置4: '2' ✅<br/>位置5: '3' ✅<br/>位置6: 'd' ❌"| G["匹配成功<br/>'123'"] G --> H{"继续搜索?"} H -->|"是"| I["位置6继续..."] I --> J["最终: ['123','456']"]
flowchart LR
    A["输入字符串<br/>abc123def456"] --> B["正则引擎"]
    B --> C{"尝试匹配<br/>r'\d+'"}
    C -->|"位置0: 'a'<br/>不是数字"| D["前进到位置1"]
    D -->|"位置1: 'b'<br/>不是数字"| E["前进到位置2"]
    E -->|"位置2: 'c'<br/>不是数字"| F["前进到位置3"]
    F -->|"位置3: '1' ✅<br/>位置4: '2' ✅<br/>位置5: '3' ✅<br/>位置6: 'd' ❌"| G["匹配成功<br/>'123'"]
    G --> H{"继续搜索?"}
    H -->|"是"| I["位置6继续..."]
    I --> J["最终: ['123','456']"]

日志解析管道

graph LR subgraph 输入 A["📄 原始日志文件<br/>每行一条记录"] end subgraph 解析层 B["🔍 正则匹配<br/>LOG_PATTERN.match(line)"] C["🧹 数据清洗<br/>类型转换/去空"] end subgraph 分析层 D["📊 统计分析<br/>状态码/IP/时间"] E["🔎 过滤查询<br/>按条件筛选"] F["📈 趋势分析<br/>时间序列"] end subgraph 输出层 G["📋 JSON 结构化<br/>可序列化"] H["📄 报告生成<br/>文本/HTML"] I["💾 存储到数据库"] end A --> B --> C --> D C --> E C --> F D --> G D --> H E --> H F --> H D --> I
graph LR
    subgraph 输入
        A["📄 原始日志文件<br/>每行一条记录"]
    end
    
    subgraph 解析层
        B["🔍 正则匹配<br/>LOG_PATTERN.match(line)"]
        C["🧹 数据清洗<br/>类型转换/去空"]
    end
    
    subgraph 分析层
        D["📊 统计分析<br/>状态码/IP/时间"]
        E["🔎 过滤查询<br/>按条件筛选"] 
        F["📈 趋势分析<br/>时间序列"]
    end
    
    subgraph 输出层
        G["📋 JSON 结构化<br/>可序列化"]
        H["📄 报告生成<br/>文本/HTML"]
        I["💾 存储到数据库"]
    end
    
    A --> B --> C --> D
    C --> E
    C --> F
    D --> G
    D --> H
    E --> H
    F --> H
    D --> I

字符编码发展历程

timeline title 字符编码发展史 1960s : ASCII 诞生 : 7位编码, 128字符 : 只有英文字母和符号 1980s : 各国本地编码 : GB2312 (中国) : Shift-JIS (日本) : 互不兼容, 乱码频发 1991 : Unicode 1.0 发布 : 统一字符集 UCS : 给每个字符一个码点 2000s : UTF-8 成为主流 : 变长编码, ASCII兼容 : 互联网/W3C 默认编码 2026 : Python 3 全面 Unicode : str 内部 Unicode : 绝大多数系统默认 UTF-8
timeline
    title 字符编码发展史
    1960s : ASCII 诞生
          : 7位编码, 128字符
          : 只有英文字母和符号
    1980s : 各国本地编码
          : GB2312 (中国)
          : Shift-JIS (日本)
          : 互不兼容, 乱码频发
    1991 : Unicode 1.0 发布
          : 统一字符集 UCS
          : 给每个字符一个码点
    2000s : UTF-8 成为主流
          : 变长编码, ASCII兼容
          : 互联网/W3C 默认编码
    2026 : Python 3 全面 Unicode
          : str 内部 Unicode
          : 绝大多数系统默认 UTF-8