使用stringr提取地名时Colombia.匹配异常的技术问询
解决正则表达式提取地名的误匹配问题
问题背景
需要从字符串中提取第一个ref. [数字]]之后到第一个有效英文句号的内容,需忽略以下带句号的特殊缩写:
km.ca.U.S.(包括U.S.A.中的U.S.结构)
当前正则表达式误将Colombia.中的a.判定为需忽略的情况,导致第一个示例提取内容包含后续无关文本,其余示例可正常工作。
问题分析
原正则表达式(?<=ref.\s[:digit:]{1,6}]\s).*?[^\s(km|ca|U\.S\.)\.](?=\.\s)存在逻辑错误:
[^\s(km|ca|U\.S\.)\.]是字符组而非分组,它会匹配任何不是空格、括号、k、m、c、a、U、.、S的字符,完全偏离了“忽略特定缩写句号”的需求。- 无法正确识别目标结束的有效句号,导致匹配范围过度延伸。
修正方案
使用负向预查断言排除需要忽略的缩写句号,确保只匹配到第一个有效句号前的内容。修正后的正则会逐个字符检查,确保当前位置不是km.、ca.或U.S.的起始位置,直到遇到第一个有效句号。
修正后的代码
library(dplyr) library(stringr) places <- tibble( text = c( "versity Studies No. 19; ref. 1259] Villavicencio, Río Orinoco system, Colombia. Holotype: FMNH 56646 [ex CM 5463]. Paratypes: (6) ", "versity Studies No. 19; ref. 1259] Villavicencio, Río Orinoco system, Colombie. Holotype: FMNH 56646 [ex CM 5463]. Paratypes: (6) ", "ions No. 457 (art. 17); ref. 2247] Roadside pool, 3 kilometers south of Progreso, Yucatán, southeastern Mexico. Holotype: UMMZ 102144. Paratypes: UMMZ 102145 (3). •Syn", "for 2001); ref. 27036] La Sapayera stream, near the bridge km. 2 vía Guadalupe-Florencia, 1°59'27\"N, 75°45'08\"W, afluent of La Viciosa stream, río Suaza system, upper Magdalena, Cachimba trail, Municipality of Guadalupe, Department of Huila, Colombia, elevation 952 meters. Holotype: IUQ 422. Par", "); ref. 30495] Rio Iguaçu, ca. 25°43'S, 49°44'W, Serrinha, Paraná, Brazil. Holotype: FMN", ". 4 (no. 2) (art. 7); ref. 1261] Corumba, río Otuquis, Ascunción, Paraguay. Holo", "); ref. 14367] Not: Puerto Mexico [Coatzacoalcos], Veracruz State, Isthmus of Tehuantepec, Mexico [probably Panama]. Holotype", "hia v. 7; ref. 168] Upper tributaries of Nueces River, Texas, U.S.A. Lectotype: BMNH 1883.12.14.107. Paralectotype" ) ) places %>% mutate( type_locality = stringr::str_extract(text, "(?<=ref\\.\\s\\d{1,6}]\\s)(?:(?!km\\.|ca\\.|U\\.S\\.).)*?(?=\\.\\s)") ) %>% relocate(type_locality)
关键正则解释
(?<=ref\\.\\s\\d{1,6}]\\s):正向回顾后发断言,锁定ref. [数字]]之后的起始位置。(?:(?!km\\.|ca\\.|U\\.S\\.).)*?:非捕获组,通过负向预查逐个字符校验,确保当前位置不是目标缩写的起始点,*?非贪婪匹配避免过度延伸。(?=\\.\\s):正向预查,匹配句号+空格的结束标记,确保提取截止到有效句号前。
验证结果
修正后所有示例均可正确提取目标地名:
- 第一个示例提取结果:
Villavicencio, Río Orinoco system, Colombia - 含
km./ca.的示例会自动跳过缩写句号,匹配到完整地名 - 含
U.S.A.的示例会跳过U.S.的句号,提取到Upper tributaries of Nueces River, Texas, U.S.A
内容的提问来源于stack exchange,提问作者Bruno Mioto
相关产品推荐
相关产品推荐

