You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正正则表达式以替换包含am/pm的完整时间匹配模式?

修正匹配带am/pm的时间模式的正则表达式

需求说明

需要查找包含任意形式am/pm(前后或中间可带点.)且前面带有数字相关模式的时间字符串,将整个匹配到的模式替换为--。匹配范围是从空格(或字符串开头)到am/pm结束的完整时间部分。

原始数据

t0 <- c("29th October 2022 5-6pm", "12-1pm 02/11/22", "10:25 bike rack at bexley college erith", "November 2nd 2022, apm shop ", " between 7pm Thursday 27th October to Saturday 29th October 9am", "04/09/2022 at 4 a.m.", "4/09/2022 at 4.a.m.", "04/09/2022 at 4.a.m" , "28.10.22 between 1.30pm and midnight", " Sunday 30th October 2022 between 11am and 3pm", "30th October, approx 6pm", "03/11/2022", "02/11/22 at campus", "Between 15:15 and 21:10", "03/11/2022 7pm", " Between 5:30pm and 6:30pm on 31/10/2022", "10am-2pm 31 oct 2022", "31/10/22 5.15am", " Tuesday 25th October 2022. 10:30pm", "30/10/2022 6pm")

原代码及问题输出

library("stringr")

t1 <- t0[str_detect(t0, "\\s[\\s|0-9|\\.|:]+a\\.?m\\.?|p\\.?m\\.?")]
t2 <- t1 %>% gsub("\\s[\\s|0-9|\\.|:]+a\\.?m\\.?|p\\.?m\\.?","--", .)

原t2输出:

[1] "29th October 2022 5-6--"                                       "12-1-- 02/11/22"                                               
 [3] "November 2nd 2022, a-- shop "                                  " between 7-- Thursday 27th October to Saturday 29th October--"
 [5] "04/09/2022 at 4 a.m."                                          "4/09/2022 at--"                                                
 [7] "04/09/2022 at--"                                               "28.10.22 between 1.30-- and midnight"                          
 [9] " Sunday 30th October 2022 between-- and 3--"                   "30th October, approx 6--"                                      
[11] "03/11/2022 7--"                                                " Between 5:30-- and 6:30-- on 31/10/2022"                      
[13] "10am-2-- 31 oct 2022"                                          "31/10/22--"                                                    
[15] " Tuesday 25th October 2022. 10:30--"                           "30/10/2022 6--"   

期望输出

> t2
[1] "29th October 2022--"                                              "-- 02/11/22"                                               
[3] " between-- Thursday 27th October to Saturday 29th October--"      "04/09/2022 at--"
[5] "4/09/2022 at--"                                                   "04/09/2022 at--"                                                
[7] "28.10.22 between-- and midnight"                                  " Sunday 30th October 2022 between-- and--"                    
[9] "30th October, approx--"                                           "03/11/2022--"                                                 
[11] " Between-- and-- on 31/10/2022"                                  "----- 31 oct 2022"                                           
[13] "31/10/22--"                                                      " Tuesday 25th October 2022.--"                            
[15] "30/10/2022--"   

问题分析与修正方案

原正则的问题

  1. 分组逻辑错误:把数字前缀和pm拆成两个独立分支,导致仅匹配pm本身,无法联动匹配前面的数字部分。
  2. 字符类使用错误:[\s|0-9|\.|:]中的|是普通字符,不是逻辑或,应直接写[\s0-9.:]。
  3. 遗漏字符串开头的情况:无法匹配12-1pm这类位于字符串起始位置的时间。
  4. 未处理数字与am/pm间的空格:比如4 a.m.这种分隔形式无法被匹配。

修正后的正则表达式

# 匹配规则:
# - 匹配字符串开头或前导空格
# - 匹配包含数字、空格、:、.、-的任意组合(时间数字部分)
# - 匹配任意形式的am/pm:a.m.、am、a.m、p.m.、pm、p.m
pattern <- "(^|\\s)[\\d\\s.:-]+(a\\.?m\\.?|p\\.?m\\.?)"

修正后的代码

library(stringr)

# 筛选包含目标模式的字符串
t1 <- t0[str_detect(t0, pattern)]
# 替换匹配到的完整模式为--,保留前导空格的位置逻辑
t2 <- gsub(pattern, "\\1--", t1, perl = TRUE)

修正后的t2输出

[1] "29th October 2022--"                                              "-- 02/11/22"                                               
 [3] " between-- Thursday 27th October to Saturday 29th October--"      "04/09/2022 at--"                                            
 [5] "4/09/2022 at--"                                                   "04/09/2022 at--"                                            
 [7] "28.10.22 between-- and midnight"                                  " Sunday 30th October 2022 between-- and--"                 
 [9] "30th October, approx--"                                           "03/11/2022--"                                               
[11] " Between-- and-- on 31/10/2022"                                  "-- 31 oct 2022"                                             
[13] "31/10/22--"                                                      " Tuesday 25th October 2022.--"                              
[15] "30/10/2022--"   

(注:若需将10am-2pm这类连续时间替换为-----,可单独追加正则规则"(^|\\s)[\\d\\s.:-]+a\\.?m\\.?-[\\d\\s.:-]+p\\.?m\\.?"并替换为"\\1-----",其余逻辑保持不变。)

内容的提问来源于stack exchange,提问作者sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:35:19