excel中有一个字符串列表,如下所示:
a>b>b>d>c>a
a>b>c>d
b>b>b>d>d>a
等。
我想从每个字符串中提取最后一个c或最后一个d,
e.g
a>b>b>d>c>a = C
a>b>c>d = d
b>b>b>d>d>a = d
我如何使用VBA (如果可能的话直接使用excel )来完成这个任务?
发布于 2016-02-12 11:51:31
这是一个数组公式来做同样的事情。(改变公式以避免“Eh”级培根指出的原问题)
=MID(A1,MAX((MID(A1,ROW(INDIRECT("1:"&LEN(A1))),1)={"c","d"})*ROW(INDIRECT("1:"&LEN(A1)))),1)
通过按住ctrl+shift
而按下enter
输入数组公式。如果操作正确,Excel将在公式栏中看到的公式周围放置大括号{...}
。
如果字符串中既没有#VALUE!
也没有c
,则公式将返回一个d
错误。
编辑:我从您的一些注释中看到,您可能希望使用的不仅仅是单个字符的单词,我展示了以下用户定义的函数。它允许你使用任意长度的单词,而且你也不局限于两个单词--你可以使用任意数量的单词。
您将输入一个公式,例如:
=LastOne(A8,"Charlie","Delta")
或
=LastOne(A8,$I1:$I2)
其中I1和I2包含您希望检查的单词。
单词需要用一个既不是字母也不是数字的分隔符分隔。
正则表达式(regex)由一个由单词或短语的管道分隔的|
列表组成。正则表达式中的管道|
与OR
相同。正则表达式开头和结尾处的\b
表示一个单词边界--这是一个数字或字母与非数字或非字母相邻的点,或字符串的开头或结尾。因此,实际的分隔符并不重要,只要它不是字母或数字。
所有的匹配都放在match Collection中;我们只需要查找匹配中的最后一项。将有MC.Count
匹配,并且,由于此计数是基于零的,我们减去1得到最后一次匹配。以下是代码:
===========================================
Option Explicit
Function LastOne(sSearch As String, ParamArray WordList() As Variant) As String
Dim RE As Object, MC As Object
Dim sPat As String
Dim RNG, C
For Each RNG In WordList
If IsArray(RNG) Or IsObject(RNG) Then
For Each C In RNG
sPat = sPat & "|" & C
Next C
Else
sPat = sPat & "|" & RNG
End If
Next RNG
sPat = "\b(?:" & Mid(sPat, 2) & ")\b"
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = sPat
.ignorecase = True
If .test(sSearch) = True Then
Set MC = .Execute(sSearch)
LastOne = MC(MC.Count - 1)
End If
End With
End Function
===========================================
下面是一个示例屏幕截图:
请注意,缺少WordList单词将导致空白单元格。如果这样做更好的话,就会产生错误。
发布于 2016-02-12 10:45:55
可以使用excel公式,如下所示
为了帮助解释,只需一个字母,然后将显示完整的公式在结尾。
首先找出c发生的次数。
= LEN(A1) - LEN(SUBSTITUTE(A1,"c","")
使用此位置将最后一个c#替换为唯一字符(以$为例)
=SUBSTITUTE(A1,"c","$",LEN(A1) - LEN(SUBSTITUTE(A1,"c","")))
接下来找出这个独特的字符
= FIND("$",SUBSTITUTE(A1,"c","$",LEN(A1) - LEN(SUBSTITUTE(A1,"c",""))))
这给出了最后一个c的位置,现在您可以在中间函数中使用它来返回最后一个c。
= MID(A1,FIND("$",SUBSTITUTE(A1,"c","$",LEN(A1) - LEN(SUBSTITUTE(A1,"c","")))),1)
最后,为了同时考虑c和d,请使用max来返回最后一个
= MID(A1,MAX(IFERROR(FIND("$",SUBSTITUTE(A1,"c","$",LEN(A1) - LEN(SUBSTITUTE(A1,"c","")))),0),IFERROR(FIND("$",SUBSTITUTE(A1,"d","$",LEN(A1) - LEN(SUBSTITUTE(A1,"d","")))),0)),1)
发布于 2016-02-12 11:16:52
假设c/d只是例子:
?LastEither("b>b>b>d>d>a", "c", "d")
d
使用
Function LastEither(testStr As String, find1 As String, find2 As String) As String
Dim p1 As Long: p1 = InStrRev(testStr, find1)
Dim p2 As Long: p2 = InStrRev(testStr, find2)
If (p1 > p2) Then
LastEither = find1
ElseIf (p2 > 0) Then LastEither = find2
End If
End Function
一般解决办法:
?FindLastMatch("b>b>b>d>d>a>q>ZZ", ">", "c", "d")
d
?FindLastMatch("b>b>b>d>d>a>q>ZZ", ">", "c", "d", "q")
q
?FindLastMatch("b>b>b>d>d>a>q>ZZ>ppp", ">", "c", "d", "ZZ", "q")
ZZ
使用
Function FindLastMatch(testStr As String, delimiter As String, ParamArray findTokens() As Variant) As String
Dim tokens() As String, i As Long, j As Long
tokens = Split(testStr, delimiter)
For i = UBound(tokens) To 0 Step -1
For j = 0 To UBound(findTokens)
If tokens(i) = findTokens(j) Then
FindLastMatch = tokens(i)
Exit Function
End If
Next
Next
End Function
https://stackoverflow.com/questions/35359830
复制相似问题