[英]find substring in a string, but look from the right to the left excel
我最初问过以下问题,发现一个好的公式excel公式在文件路径文本字符串中找到零件号
因此,在使用=MID(A1,SEARCH("????-??????-??",A1),14)
公式查找零件代号名称之后,一切似乎都很好,直到我遇到了看起来像这样的数据像下面的示例集。
c:\users\stuff\folder_name\folder_name_9876-vv-123-Ag\1234-000001-01_ baskets_1.pdf
c:\users\stuff\folder_name_9876-vv-123-Ag\random file_1234-000001-02_ baskets_2.pdf
c:\users\stuff\folder_name_XXXX-XXXXXX-XX\1234-000001-03_ baskets_3.pdf
c:\users\stuff\folder_name\1234-000030-01_ tree_30.pdf
c:\users\stuff\folder_name\random text_1234-000030-02_ tree_30.pdf
c:\users\stuff\folder_name\more random stuff_1234-000030-02_ tree_30.pdf
我正在浏览数十万个文件名,并且我知道由于误报触发而丢失了一些重要文件。 像9876-vv-123-Ag
它在技术上适合????-??????-??
格式,但不是我要从字符串中提取的格式。 现在到问题所在,有没有一种方法可以应用=MID(A1,SEARCH("????-??????-??",A1),14)
从字符串的右侧看并向左移动以确保它抓住了完整字符串中符合????-??????-??
的最后一个子字符串 格式?
或者有一种方法可以将通配符搜索设置为仅数字形式,而不是其中的任何形式????-??????-??
格式?
如果没有其他歧义,则可以仅搜索文件路径的文件名部分,然后返回匹配的字符串:
=MID(TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",99)),99)),SEARCH("????-??????-??",TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",99)),99))),14)
如果还有其他歧义,您将需要更加具体
公式的这一部分: TRIM(RIGHT(SUBSTITUTE(A1,"\\",REPT(" ",99)),99))
返回最后一个子字符串,该字符串在“ \\”字符上进行了拆分。 如果它可能是文件名可能有超过99个字符的情况下,再增加99恰当,或使用类似LEN(A1)
来代替。
如果要使用VBA例程,则以下例程在不到4秒的时间内处理了500,000行。 它确实取决于仅由数字组成的部件号,但是如果需要包括其他模式,则更改将是微不足道的。
Option Explicit
Sub partNum()
Dim RE As Object
Dim R As Range, WS As Worksheet
Dim vSrc As Variant, vRes As Variant
Dim I As Long
Set WS = Worksheets("sheet1")
With WS
vSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
Set R = .Range(.Cells(1, 2), .Cells(UBound(vSrc, 1), 2))
End With
ReDim vRes(1 To UBound(vSrc, 1), 1 To 1)
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = "\d{4}-\d{6}-\d{2}"
For I = 1 To UBound(vSrc)
If .test(vSrc(I, 1)) = True Then vRes(I, 1) = .Execute(vSrc(I, 1))(0)
Next I
End With
R.EntireColumn.Clear
R = vRes
End Sub
VBA功能 (独立)
Option Explicit
Function getPartNum(S As String) As String
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Pattern = "\d{4}-\d{6}-\d{2}(?!.*\\)"
If .test(S) = True Then getPartNum = .Execute(S)(0)
End With
End Function
仅适用于2个可能出现的选择最后一个字符串的字符串。
=IF(ISERROR(SEARCH("????-??????-??";A2));"";IF(ISERROR(SEARCH("????-??????-??";A2;SEARCH("????-??????-??";A2)+1));MID($A2;SEARCH("????-??????-??";A2);LEN("????-??????-??"));MID($A2;SEARCH("????-??????-??";A2;SEARCH("????-??????-??";A2)+1);LEN("????-??????-??"))))
Sub SearchQ2()
Const cStrSource As String = "A2"
Const cStrTarget As String = "B2"
Const cStrSearch As String = "????-??????-??"
Dim vntRange As Variant
Dim lngSearch As Long
Dim intStart As Integer
Dim lng1 As Long
Dim strTemp As String
vntRange = Range(cStrSource).Resize(Cells(Rows.Count, Range("A1").Column) _
.End(xlUp).Row - Range(cStrSource).Row + 1)
For lng1 = 1 To UBound(vntRange)
intStart = 1
Do
On Error Resume Next
lngSearch = WorksheetFunction.Search(cStrSearch, _
vntRange(lng1, 1), intStart)
If Err Then
Exit Do
Else
strTemp = Mid(vntRange(lng1, 1), lngSearch, Len(cStrSearch))
intStart = lngSearch + Len(cStrSearch) + 1
End If
Loop
vntRange(lng1, 1) = strTemp
Next
Range(cStrTarget).Resize(Cells(Rows.Count, Range("A1").Column) _
.End(xlUp).Row - Range(cStrSource).Row + 1) = vntRange
End Sub
对于一百个,甚至几百个细胞,它都可以正常工作。 这可能是某人编写高效函数的灵感。
它遍历字符串以查找最后一次出现的SearchString。
Function SearchQ(SearchString As String, Cell As Range) As String
Application.Volatile
Dim lngSearch As Long
Dim intStart As Integer
intStart = 1
Do
On Error Resume Next
lngSearch = WorksheetFunction.Search(SearchString, _
Cell.Cells(1, 1).Text, intStart)
If Err Then
Exit Do
Else
SearchQ = Mid(Cell.Cells(1, 1).Text, lngSearch, Len(SearchString))
intStart = lngSearch + Len(SearchString) + 1
End If
Loop
End Function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.