如何使用preg_match匹配带点格式圣经经节并提取卷名、章、节信息
preg_match匹配圣经经节问题修正
错误原因
原有代码无法正确提取信息,核心问题有两个:
- 正则里章和节的分隔符写的是冒号
:,但目标格式是用点号.分隔章、节 - 经卷名的捕获规则错误:捕获组开头强制要求匹配1位数字,对于没有数字前缀的经卷(如Hebrews、Romans),会把后续章号的第一位数字抢到经卷名分组中,同时经卷名本身的字符没有被正确捕获,最终导致分组错位。
修正后代码
if (preg_match('/^\s*(\d?\s*[a-zA-ZàâäæáãåāèéêëęėēîïīįíìôōøõóòöœùûüūúÿçćčńñÀÂÄÆÁÃÅĀÈÉÊËĘĖĒÎÏĪĮÍÌÔŌØÕÓÒÖŒÙÛÜŪÚŸÇĆČŃÑ]+)\s*(\d{1,3})\s*\.\s*(\d{1,3})\s*$/', $bible_passage, $ourmatches)) { $book = trim($ourmatches[1]); $chapter = $ourmatches[2]; $verse = $ourmatches[3]; echo "Book $book Chapter $chapter verse $verse"; }
匹配效果
针对给出的所有测试用例,输出完全符合预期:
- 输入
Hebrews 11.6:输出 Book Hebrews Chapter 11 verse 6 - 输入
2 Chronicles 10.16:输出 Book 2 Chronicles Chapter 10 verse 16 - 输入
Romans 13.13:输出 Book Romans Chapter 13 verse 13 - 输入
2 Kings 5.10:输出 Book 2 Kings Chapter 5 verse 10 - 输入
3 John 1.5:输出 Book 3 John Chapter 1 verse 5
正则逻辑说明
^\s*:匹配字符串起始位置,兼容开头存在空白字符的情况(\d?\s*[a-zA-Zàâä...Ñ]+):第一个捕获组对应经卷名,开头的\d?表示可选匹配1位数字前缀(适配2 Kings、3 John这类带数字前缀的经卷),后续匹配经卷名的字母部分,兼容所有带变音符号的西文字符\s*(\d{1,3})\s*:第二个捕获组对应1-3位长度的章号,兼容章号前后存在空格的情况\.\s*:匹配章和节之间的点号分隔符,兼容点号后存在空格的情况(\d{1,3})\s*$:第三个捕获组对应1-3位长度的节号,匹配到字符串末尾,避免多余字符造成误匹配
内容的提问来源于stack exchange,提问作者John Max
相关产品推荐
相关产品推荐

