在 Excel 中保持正则表达式匹配的最佳方法是什么?
What's the best way to keep regex matches in Excel?
我正在研究“如何在 Microsoft Excel 单元格内和循环中使用正则表达式 (Regex)”中提供的优秀信息,但是我 运行一堵墙试图保留匹配的表达式,而不是不匹配的部分:
在电子表格中使用该函数时,“2022-02-14T13:30:00.000Z”会转换为“T13:30:00.000Z”而不是“2022-02-14”。下面列出的代码取自“如何在 Microsoft Excel 单元格和循环中使用正则表达式 (Regex)”。我虽然对 strPattern2 的否定会起作用,但我仍然遇到问题。非常感谢任何帮助。
Function simpleCellRegex(Myrange As Range) As String
Dim regEx As New RegExp
Dim strPattern As String
Dim strPattern2 As String
Dim strInput As String
Dim strReplace As String
Dim strOutput As String
strPattern = "^T{0-9][0-9][:]{0-9][0-9][:]{0-9][0-9][0-9][Z]"
strPattern2 = "^(19|20)\d\d([- /.])(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])"
If strPattern2 <> "" Then
strInput = Myrange.Value
strReplace = ""
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern2
End With
If regEx.test(strInput) Then
simpleCellRegex = regEx.Replace(strInput, strReplace)
Else
simpleCellRegex = "Not matched"
End If
End If
End Function
替换非常强大,但您需要做两件事:
- 指定您要删除的所有字符,如果您的正则表达式是 <myregexp>,然后将其更改为
^.*?(<myregexp>).*$
,假设您的日期中只有一个日期出现细绳。括号称为 'capturing group' ,您可以稍后在替换模式中引用它们。开头的 ^ 和结尾的 $ 确保即使 Global=True,您也只会匹配一次模式。我注意到您已经在使用捕获组作为反向引用——您需要向反向引用编号添加一个,因为我们添加了一个捕获组。以这种方式设置模式,整个字符串将参与匹配,我们将使用捕获组来保留我们想要保留的内容。
- 将您的
strReplace=""
更改为 strReplace=""
,表示您要替换与捕获组 #1 的内容匹配的任何内容。
这是来自 Excel 的屏幕截图,使用我的 RegexpReplace 用户定义函数根据我的建议处理您的示例:
我不得不修正你的时间部分正则表达式,因为你在表示正方形的地方使用了三次大括号,而你完全遗漏了秒部分。请注意,通过调整捕获组括号的开始和结束位置,您可以在时间字符串的任一端保留或删除 T & Z。
此外,如果您的程序从可靠来源传递系统时间戳,那么它们已经是格式正确的,您不需要那些很长很长的正则表达式来拒绝 3 月 32 日。您可以将这两个部分合二为一作为
([-0-9/.]{10,10})T([0-9:.]{12,12})Z
当您想要日期部分时使用 $1,当您想要时间部分时使用 $2。
我正在研究“如何在 Microsoft Excel 单元格内和循环中使用正则表达式 (Regex)”中提供的优秀信息,但是我 运行一堵墙试图保留匹配的表达式,而不是不匹配的部分:
在电子表格中使用该函数时,“2022-02-14T13:30:00.000Z”会转换为“T13:30:00.000Z”而不是“2022-02-14”。下面列出的代码取自“如何在 Microsoft Excel 单元格和循环中使用正则表达式 (Regex)”。我虽然对 strPattern2 的否定会起作用,但我仍然遇到问题。非常感谢任何帮助。
Function simpleCellRegex(Myrange As Range) As String
Dim regEx As New RegExp
Dim strPattern As String
Dim strPattern2 As String
Dim strInput As String
Dim strReplace As String
Dim strOutput As String
strPattern = "^T{0-9][0-9][:]{0-9][0-9][:]{0-9][0-9][0-9][Z]"
strPattern2 = "^(19|20)\d\d([- /.])(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])"
If strPattern2 <> "" Then
strInput = Myrange.Value
strReplace = ""
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern2
End With
If regEx.test(strInput) Then
simpleCellRegex = regEx.Replace(strInput, strReplace)
Else
simpleCellRegex = "Not matched"
End If
End If
End Function
替换非常强大,但您需要做两件事:
- 指定您要删除的所有字符,如果您的正则表达式是 <myregexp>,然后将其更改为
^.*?(<myregexp>).*$
,假设您的日期中只有一个日期出现细绳。括号称为 'capturing group' ,您可以稍后在替换模式中引用它们。开头的 ^ 和结尾的 $ 确保即使 Global=True,您也只会匹配一次模式。我注意到您已经在使用捕获组作为反向引用——您需要向反向引用编号添加一个,因为我们添加了一个捕获组。以这种方式设置模式,整个字符串将参与匹配,我们将使用捕获组来保留我们想要保留的内容。 - 将您的
strReplace=""
更改为strReplace=""
,表示您要替换与捕获组 #1 的内容匹配的任何内容。
这是来自 Excel 的屏幕截图,使用我的 RegexpReplace 用户定义函数根据我的建议处理您的示例:
我不得不修正你的时间部分正则表达式,因为你在表示正方形的地方使用了三次大括号,而你完全遗漏了秒部分。请注意,通过调整捕获组括号的开始和结束位置,您可以在时间字符串的任一端保留或删除 T & Z。
此外,如果您的程序从可靠来源传递系统时间戳,那么它们已经是格式正确的,您不需要那些很长很长的正则表达式来拒绝 3 月 32 日。您可以将这两个部分合二为一作为
([-0-9/.]{10,10})T([0-9:.]{12,12})Z
当您想要日期部分时使用 $1,当您想要时间部分时使用 $2。