精选类型(parse_types)¶
概述¶
infinity_parse.parse_types 提供一批开箱即用的转换器类型(Annotated 别名),命名与
语义对齐 parse 库的格式符({:d}、{:%Y-%m-%d} 等)。全部类型都只是普通的类型
别名,直接放进 scan[...] 的类型参数即可:
from infinity_parse import scan
from infinity_parse import parse_types as t
scan[t.Int, t.SimpleDate]("{} {}")("42 2024-01-15") # (42, date(2024, 1, 15))
字符类¶
| 类型 | 输入示例 | 结果 | 对应 parse | 说明 |
|---|---|---|---|---|
t.Letters |
abcXYZ |
"abcXYZ" |
{:l} |
纯 ASCII 字母([a-zA-Z]+) |
t.Word |
a_1 |
"a_1" |
{:w} |
字母、数字、下划线(\w+) |
t.NonWord |
!! |
"!!" |
{:W} |
非 \w 字符(\W+) |
t.Whitespace |
" " |
" " |
{:s} |
保留原始空白(strip=False) |
t.NonWhitespace |
x |
"x" |
{:S} |
非空白(\S+) |
t.NonDigit |
x |
"x" |
{:D} |
非数字(\D+) |
t.Whitespace有两个使用要点:字段保留原始空白(不 strip);但scan会先 strip 整个输入,纯空白输入需要使用scanall/search(它们不 strip 输入)。
from infinity_parse import scanall
from infinity_parse import parse_types as t
scanall[t.Whitespace]("{}")("a b") # [(" ",)]
日期与时间¶
| 类型 | 输入示例 | 结果 | 对应 parse |
|---|---|---|---|
t.SimpleDate |
2024-01-15 |
date(2024, 1, 15) |
{:%Y-%m-%d} |
t.SimpleTime |
12:30 / 12:30:45 |
time(12, 30) / time(12, 30, 45) |
{:%H:%M} 一族 |
t.IsoDateTime |
2024-01-15T12:30:45+08:00 |
带时区 datetime |
{:ti} |
t.Rfc2822DateTime |
Mon, 20 Jan 1972 10:21:36 +1000 |
带时区 datetime |
{:te} |
t.GlobalDate |
20/1/1972 10:21:36 AM +1:00 |
datetime |
{:tg} |
t.UsDate |
1/20/1972 10:21:36 PM +10:30 |
datetime |
{:ta} |
t.CtimeDateTime |
Sun Sep 16 01:03:52 1973 |
datetime |
{:tc} |
t.HttpLogDateTime |
21/Nov/2011:00:07:11 +0000 |
带时区 datetime |
{:th} |
t.SyslogDateTime |
Nov 9 03:37:44 |
datetime(补当前年) |
{:ts} |
t.AmPmTime |
10:21:36 PM / 10:21 |
time(AM/PM 与时区可选) |
{:tt} |
t.GlobalDate/t.UsDate的日期部分必填,时间、AM/PM 与时区偏移均可选; 12 小时制会自动换算(PM加 12 小时)。t.IsoDateTime接受T或空格分隔、可省略秒、支持Z后缀与+08:00偏移。
数字¶
| 类型 | 输入示例 | 结果 | 对应 parse | 说明 |
|---|---|---|---|---|
t.CommaInt |
1,234,567 / 1.234.567 |
1234567 |
{:n} |
必须带千分位分隔符 |
t.Percent |
12.5% / -.5% |
0.125 / -0.005 |
{:%} |
百分数转小数 |
t.HexInt |
0x1F / FF |
31 / 255 |
{:x} |
前缀可选 |
t.Int |
42 / -0x1F / 0b101 / -0o17 |
42 / -31 / 5 / -15 |
{:d} |
支持 0x / 0b / 0o 前缀;042 按十进制 |
t.Binary |
0b101 / 101 |
5 |
{:b} |
前缀可选 |
t.Octal |
0o17 / 17 |
15 |
{:o} |
前缀可选 |
t.Float |
-1.5 / .5 |
-1.5 |
{:f} |
必须带小数点(1、1. 不匹配) |
t.ExponentFloat |
1.1e-10 / NAN / INF |
1.1e-10 |
{:e} |
必须带指数;特殊值大小写不敏感 |
t.GeneralFloat |
42 / 1.5 / 4.2e1 |
42.0 |
{:g} |
统一转 float |
t.DecimalNumber |
1.5 |
Decimal("1.5") |
{:F} |
必须带小数点,返回 decimal.Decimal |
从字面量构建类型¶
两个泛型构建器可以把「字面模式 / 字面格式串」直接变成类型。
RegexString¶
t.RegexString[Literal[pattern]] 在运行时解析为
Annotated[str, Converter(str, pattern=...)];类型检查器看到的是携带模式的 str
子类型,默认 str 的行为不受影响。
from typing import Literal
from infinity_parse import scan
from infinity_parse.parse_types import RegexString
type DashPair = RegexString[Literal[r"\d+-\d+"]]
scan[DashPair]("{}")("12-34") # ('12-34',)
DateTime¶
t.DateTime[Literal[fmt]] 由 strptime 格式串推导捕获模式,转换时用同一格式串解析:
from typing import Literal
from infinity_parse import scan
from infinity_parse.parse_types import DateTime
type LogStamp = DateTime[Literal["%Y-%m-%d %H:%M:%S"]]
scan[LogStamp]("{}")("2024-01-15 12:30:45")
# (datetime(2024, 1, 15, 12, 30, 45),)
已内置的 t.CtimeDateTime 与 t.HttpLogDateTime 正是这类别名:
DateTime[Literal["%a %b %d %H:%M:%S %Y"]] 与
DateTime[Literal["%d/%b/%Y:%H:%M:%S %z"]]。
支持的指令为常用子集:a A b B d f H I j m M p S y Y z Z %;不支持的指令
(如 %Q)在构造时抛 TypeError。
使用示例¶
from infinity_parse import scan
from infinity_parse import parse_types as t
# 混用内置类型与精选类型
scan[t.Int, t.Percent]("{} {}")("42 12.5%") # (42, 0.125)
# 同一模板重复使用同一种类型(捕获模式内不含命名分组,不会冲突)
scan[t.SimpleDate, t.SimpleDate]("{} {}")(
"2024-01-15 2025-02-03"
) # (date(2024, 1, 15), date(2025, 2, 3))
注意事项¶
t.SyslogDateTime的 syslog 时间戳不带年份:转换器补当前年份 (与parse一致)。t.Whitespace保留原始空白,但scan先 strip 整个输入:纯空白输入请使用scanall/search。t.Float、t.DecimalNumber必须带小数点;t.CommaInt必须带千分位——这些 「严格性」与parse的对应格式符一致。- 校验失败分两层:模式不匹配 →
MatchError;模式匹配但值非法(如2024-13-45) →ConvertError。 - 精确匹配语义随所选的
scan/search/scanall模式(见 scanner.md)。