如何匹配字符串末尾的子串,然后只删除该子串?
How to match a substring at the end of a string, and then delete only that substring?
我在每个单元格中有一列文本,其中许多单元格的末尾都有字符串 null
。如果单元格的内容以该字符串结尾,我想解析列中的每个单元格并从单元格中删除 just null
。
到目前为止,如果 null
和前面的单词之间有一个 space,我所写的内容成功地从末尾删除了 null
,但删除了 整个单元格的 前面的单词和 null
之间没有 space 的内容。
Sub TruncateNulls()
Dim strPattern As String: strPattern = "\w*null\b"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String
ActiveSheet.Range("A2").Select
Do While ActiveCell.Value <> ""
strInput = ActiveCell.Value
With regEx
.Global = False
.MultiLine = True
.IgnoreCase = True
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
ActiveCell = regEx.Replace(strInput, strReplace)
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
示例输入数据:
words
null
wordsnull
words null
nullwords
需要的输出数据:
words
words
words
nullwords
我如何调整它以仅删除结尾 null
,而不考虑前面的字符?
或者,我愿意使用 Excel 的 Find
功能,或搜索和替换 window 中的特定 wildcard/wildcard 组合,如果这些选项有效。
如果您更喜欢当前的方法,则需要将您的模式替换为
\s*null\s*$
详情
\s*
- 0+ whitespaces(如果不想跨行溢出,请将 \s
替换为 space 或 [^\S\r\n]
null
- null
子字符串
\s*
- 1个或多个白色spaces(见上面相同的注释)
$
- 行尾(将 .Multiline
标志设置为 False 以匹配字符串的结尾)。
在这种情况下,比正则表达式更简单的是使用 Right()
函数检查最后 4 个字符。您的代码可以减少到
Do While ActiveCell.Value <> ""
strInput = ActiveCell.Value
If Right(strInput, 4) = "null" Then
ActiveCell.Value = Left(strInput, Len(strInput)-4)
End If
ActiveCell.Offset(1, 0).Select
Loop
据我了解,这也更有效(并且可以通过定义范围并将其值复制到数组来提高效率)。
使用 .Replace
和模式 \s*null$
删除每个单元格末尾的所有匹配项。您还应该考虑将范围加载到数组中以缩短执行时间。
Sub TruncateNulls()
Dim rg As Range, data()
' select the range to the last row
Set rg = Range(Range("A2"), Range("A" & rows.Count).end(xlUp))
' load the data in an array
data = rg.value
' replace each value with a regex
ArrayReplace data, pattern:="\s*null$", replacement:=Empty
' write the array back to the sheet
rg.value = data
End Sub
Sub ArrayReplace(data(), pattern As String, replacement As String)
Dim re As New RegExp, r As Long, c As Long
re.Global = True
re.MultiLine = False
re.IgnoreCase = True
re.pattern = pattern
For c = 1 To UBound(data, 2)
For r = 1 To UBound(data, 1)
If VarType(data(r, c)) = vbString Then
data(r, c) = re.Replace(data(r, c), replacement)
End If
Next
Next
End Sub
我在每个单元格中有一列文本,其中许多单元格的末尾都有字符串 null
。如果单元格的内容以该字符串结尾,我想解析列中的每个单元格并从单元格中删除 just null
。
到目前为止,如果 null
和前面的单词之间有一个 space,我所写的内容成功地从末尾删除了 null
,但删除了 整个单元格的 前面的单词和 null
之间没有 space 的内容。
Sub TruncateNulls()
Dim strPattern As String: strPattern = "\w*null\b"
Dim strReplace As String: strReplace = ""
Dim regEx As New RegExp
Dim strInput As String
ActiveSheet.Range("A2").Select
Do While ActiveCell.Value <> ""
strInput = ActiveCell.Value
With regEx
.Global = False
.MultiLine = True
.IgnoreCase = True
.Pattern = strPattern
End With
If regEx.Test(strInput) Then
ActiveCell = regEx.Replace(strInput, strReplace)
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
示例输入数据:
words
null
wordsnull
words null
nullwords
需要的输出数据:
words
words
words
nullwords
我如何调整它以仅删除结尾 null
,而不考虑前面的字符?
或者,我愿意使用 Excel 的 Find
功能,或搜索和替换 window 中的特定 wildcard/wildcard 组合,如果这些选项有效。
如果您更喜欢当前的方法,则需要将您的模式替换为
\s*null\s*$
详情
\s*
- 0+ whitespaces(如果不想跨行溢出,请将\s
替换为 space 或[^\S\r\n]
null
-null
子字符串\s*
- 1个或多个白色spaces(见上面相同的注释)$
- 行尾(将.Multiline
标志设置为 False 以匹配字符串的结尾)。
在这种情况下,比正则表达式更简单的是使用 Right()
函数检查最后 4 个字符。您的代码可以减少到
Do While ActiveCell.Value <> ""
strInput = ActiveCell.Value
If Right(strInput, 4) = "null" Then
ActiveCell.Value = Left(strInput, Len(strInput)-4)
End If
ActiveCell.Offset(1, 0).Select
Loop
据我了解,这也更有效(并且可以通过定义范围并将其值复制到数组来提高效率)。
使用 .Replace
和模式 \s*null$
删除每个单元格末尾的所有匹配项。您还应该考虑将范围加载到数组中以缩短执行时间。
Sub TruncateNulls()
Dim rg As Range, data()
' select the range to the last row
Set rg = Range(Range("A2"), Range("A" & rows.Count).end(xlUp))
' load the data in an array
data = rg.value
' replace each value with a regex
ArrayReplace data, pattern:="\s*null$", replacement:=Empty
' write the array back to the sheet
rg.value = data
End Sub
Sub ArrayReplace(data(), pattern As String, replacement As String)
Dim re As New RegExp, r As Long, c As Long
re.Global = True
re.MultiLine = False
re.IgnoreCase = True
re.pattern = pattern
For c = 1 To UBound(data, 2)
For r = 1 To UBound(data, 1)
If VarType(data(r, c)) = vbString Then
data(r, c) = re.Replace(data(r, c), replacement)
End If
Next
Next
End Sub