
本文详解如何使用 PHP 的 preg_match 正确解析含数字前缀(如“2 Chronicles”)或纯名称(如“Hebrews”)的圣经经文字符串,准确分离书卷名、章号和节数,并保持原始命名顺序。
本文详解如何使用 php 的 `preg_match` 正确解析含数字前缀(如“2 chronicles”)或纯名称(如“hebrews”)的圣经经文字符串,准确分离书卷名、章号和节数,并保持原始命名顺序。
在处理圣经经文文本时,常见格式如 Hebrews 11.6、2 Chronicles 10.16 或 3 John 1.5,其结构看似简单,但因存在可选的前置序数词(如 "2"、"3")、多词书卷名(如 "2 Chronicles"、"3 John")以及统一使用的英文句点分隔符(.),传统正则易误捕或错位分组。原代码中使用 ([0-9]{1}[ ]{0,}[a-zA-Z...]+) 试图一次性匹配书名,却将开头数字错误纳入书名捕获组,导致 Hebrews 11.6 被误判为 Book 1 Chapter 11 verse 6。
正确方案应采用非贪婪、结构化分组,明确区分「前置序数词(可选)」「书卷主名称」「章号」「节数」四部分。推荐正则模式如下:
/(?:(\d+)\s+)?(\w+(?:\s+\w+)*)\s+(\d+)\.(\d+)/
- (?:(\d+)\s+)?:非捕获组内捕获可选的序数(如 2、3),后跟至少一个空白;
- (\w+(?:\s+\w+)*):捕获书卷名,支持单词(Hebrews)或多词(Chronicles、John),注意此处不包含前置数字,确保 2 Chronicles 中 2 属于第一组,Chronicles 属于第二组;
- \s+(\d+)\.(\d+):匹配空格、章号、英文句点、节数,分别捕获为第三、第四组。
完整可运行示例:
<?php
$verses = [
"Hebrews 11.6",
"2 Chronicles 10.16",
"Romans 13.13",
"2 Kings 5.10",
"3 John 1.5"
];
foreach ($verses as $verse) {
if (preg_match('/(?:(\d+)\s+)?(\w+(?:\s+\w+)*)\s+(\d+)\.(\d+)/', $verse, $matches)) {
$volume = $matches[1] ?? null; // 如 "2", "3"
$book = $matches[2]; // 如 "Chronicles", "John"
$chapter = $matches[3]; // 如 "10", "1"
$verse_num = $matches[4]; // 如 "16", "5"
// 拼接输出:保持原始语义(如 "2 Chronicles" → volume=2, book="Chronicles")
echo "Book {$book}";
if ($volume) {
echo " volume {$volume}";
}
echo " chapter {$chapter} verse {$verse_num}\n";
}
}输出结果:
Book Hebrews chapter 11 verse 6 Book Chronicles volume 2 chapter 10 verse 16 Book Romans chapter 13 verse 13 Book Kings volume 2 chapter 5 verse 10 Book John volume 3 chapter 1 verse 5
⚠️ 注意事项:
- 该正则假设书卷名仅由字母与空格组成(支持 Unicode 可扩展为 [\p{L}\s] 并添加 u 修饰符);
- 若需兼容 1 Corinthians 等带罗马数字的变体,建议预处理标准化为阿拉伯数字,或增强书名匹配逻辑;
- 实际项目中建议封装为函数,并加入 trim() 和空匹配校验,提升健壮性;
- 英文句点 . 是圣经引用的标准分隔符,切勿替换为冒号 : 或连字符,否则将导致匹配失败。
此方案兼顾准确性与可维护性,避免过度复杂的字符类,专注语义结构,是解析标准英文圣经引用的可靠实践。

















