范例 |
正则表达式范例 |
数字范围 |
浮点数 |
电子邮件地址 |
IP 地址 |
有效的日期 |
数字日期转文本 |
信用卡号码 |
符合完整行 |
删除重复行 |
编程 |
两个相近的字词 |
陷阱 |
灾难性的回溯 |
重复太多次 |
拒绝服务 |
让所有东西都可选择 |
重复的捕获组 |
混合 Unicode 和 8 比特 |
此网站的更多信息 |
简介 |
正则表达式快速入门 |
正则表达式教程 |
替换字符串教程 |
应用程序和语言 |
正则表达式范例 |
正则表达式参考 |
替换字符串参考 |
用文本日期取代数字日期
此范例显示如何将 1/1/50 或 01/01/50 到 12/31/49 的数字日期替换为文本等效日期,从 1950 年 1 月 1 日到 2049 年 12 月 31 日。如果你可以根据匹配的内容改变替换,则只需一个正则表达式就能做到这一点。运行此操作的一种方法是在进程码中创建每个替换。此范例显示如何使用替换字符串条件来运行此操作。此范例可搭配Boost C++ 函数库和PCRE2 C 函数库使用。
若要能够使用替换字符串条件,正则表达式需要为需要不同替换的每一个比对部分创建一个独立的捕获组。每个月份都需要替换成其名称,因此我们需要一个独立的捕获组来比对每个月份号码。以 1、2 和 3 结尾的基数需要有独特的后缀。因此我们需要四个群组来比对以 1、2、3 或其他数字结尾的日期号码。我们假设年份号码 50 至 99 为 1950 至 1999,而年份号码 00 至 49 为 2000 至 2049。因此我们需要再两个群组来比对每个半世纪。
正则表达式
将这一切组合在一起会产生一个相当长的正则表达式。 自由间距 有助于保持其可读性。正则表达式的结构与您用于 比对有效日期 的结构相同。它只会更冗长,因为我们需要 12 个 选项 来比对月份、4 个选项来比对日期,以及 2 个选项来比对年份。
\b
(?: # Month
(?'jan'0?1)|(?'feb'0?2)|(?'mar'0?3)|(?'apr'0?4)|(?'may'0?5)|(?'jun'0?6)
|(?'jul'0?7)|(?'aug'0?8)|(?'sep'0?9)|(?'oct'10)|(?'nov'11)|(?'dec'12)
) /
0?(?: # Day
(?'1st'[23]?1)|(?'2nd'2?2)|(?'3rd'2?3)|(?'nth'30|1[123]|[12]?[4-90])
) /
(?: # Year
(?'19xx'[5-9][0-9])|(?'20xx'[0-4][0-9])
)
\b
替换字符串
替换字符串将使用反向引用来重新插入日期号码。由于我们希望从替换中省略前导零,因此我们将 0?
放在日期号码的捕获组之外。这表示我们的正则表达式也允许 10 至 31 日的前导零。由于我们的目标是替换日期,而不是验证它们,因此我们可以接受这一点。否则,我们将需要两组四个选项来比对月份中的日期。一组用于个位数日期,一组用于两位数日期。
很遗憾,自由间距不适用于替换字符串。因此替换包含一行非常长的字符串。它在此处分成多行以符合页面宽度。这是使用 Boost 语法的替换
(?{jan}一月)(?{feb}二月)(?{mar}三月)(?{apr}四月)(?{may}五月)(?{jun}六月)
(?{jul}七月)(?{aug}八月)(?{sep}九月)(?{oct}十月)(?{nov}十一月)
(?{dec}十二月) (?{1st}${1st}日)(?{2nd}${2nd}日)(?{3rd}${3rd}日)(?{nth}${nth}日)
, (?{19xx}19${19xx})(?{20xx}20${20xx})
这是使用 PCRE2 语法的替换
${jan:+一月}${feb:+二月}${mar:+三月}${apr:+四月}${may:+五月}${jun:+六月}
${jul:+七月}${aug:+八月}${sep:+九月}${oct:+十月}${nov:+十一月}
${dec:+十二月} ${1st:+${1st}日}${2nd:+${2nd}日}${3rd:+${3rd}日}${nth:+${nth}日}
, ${19xx:+19${19xx}}${20xx:+20${20xx}}
首先,我们有 12 个条件式,参考 12 个用于月份的捕获组。每个条件式会在群组参与时插入月份名称。当群组未参与时,它们不会插入任何内容。由于在任何比对中只会有一个群组参与,因此只会有一个条件式实际插入任何内容到替换中。
接着,我们有一个文本空格和另外 4 个条件式,参考 4 个用于日期的捕获组。当群组参与时,条件式会使用 反向引用 到同一个群组,以重新插入群组比对到的日期数字。反向引用后接一个文本后缀。
最后,我们有一个文本逗号、一个文本空格和另外 2 个条件式,用于年份。条件式再次使用文本和反向引用,将年份从 2 位数扩充为 4 位数。