【问题标题】:Is there an easy way to check if the string starts with letters (any 4 letters)?有没有一种简单的方法来检查字符串是否以字母开头(任何 4 个字母)?
【发布时间】:2020-04-14 13:08:35
【问题描述】:

有没有办法检查字符串是否以任意 4 个字母开头。我正在寻找这样的东西:

If string like "####*" then
'DO STUFF
end if

“#”用于数字,我需要同样的东西,但只用于字母。 这可以在没有 regEx 的情况下完成吗?

【问题讨论】:

  • 我不知道任何只匹配文本的通配符,以及documentation doesn't provide any either。正则表达式通常被认为是the easiest solution
  • @Plutian,这很有可能 =)。好问题,因为它实际上有点奇怪,没有简单的字母通配符。
  • @Radas - 为了艺术和除了问题之外的后期帖子*“可以在没有 RegEx 的情况下完成吗?”* 演示如何使用 FilterXML() 函数作为替代:- )

标签: excel vba string letter


【解决方案1】:

我不知道不使用正则表达式的方法。我们可以尝试使用正则表达式Test 以及模式^[A-Z]{4}.*$

Dim input As String
Dim regex As Object
Set regex = New RegExp

regex.Pattern = "^[A-Z]{4}.*$"
input = "ABCD blah"

If regex.Test(input) Then
    'DO STUFF
End If

【讨论】:

  • Like 运算符在它的袖子上有一些技巧,以防止在这种情况下使用 RegEx。尽管如此,我也喜欢这个解决方案 ++
  • 小评论,刚刚注意到(我不是 RegEx 专家),但您不想使用"^[A-Za-z]{4}"。你介意简单解释一下为什么.*$吗?我猜这是在寻找任何非换行符,直到字符串结束。但为什么?稍后将删除评论;)
  • ^ 是一个锚点,确保定义的模式必须出现在字符串的开头。不会吗?
  • 仅供参考 - 您可能会对我使用 FilterXML() 函数的方法感兴趣(除了 JvdV 的有效解决方案),正如您提到的 “我不知道不使用常规的方法来做到这一点表达式" :-) @TimBiegeleisen
【解决方案2】:

您可以使用Like 几乎与使用 RegEx 相同。

"{#}" - Like 运算符中不存在,但 "[A-Z]" 绝对有效

if string like "[A-Z][A-Z][A-Z][A-Z]*" then
   'DO STUFF
end if

【讨论】:

  • If str Like "[a-zA-Z][a-zA-Z][a-zA-Z][a-zA-Z]*" 然后也要考虑小写:)。不错的解决方案,我也添加了另一个版本 =)。 ++
  • 现在最大的问题是调用完整的正则表达式是否比您的答案差很多。
【解决方案3】:

可以不使用正则表达式吗?

是的,没有特别需要Regular Expressions,因为Like 操作符非常有能力作为某种最后手段来处理这种情况,就像this 文章的作者所解释的那样。此外,RegEx 在较大的数据库上有点慢。尽管如此,RegEX 是一个很棒的工具!

@AlexandruHapco 提供的解决方案会告诉您字符串是否以 4 个大写字母开头。但要考虑下或上,你可以扩展这个逻辑:

If str Like "[a-zA-Z][a-zA-Z][a-zA-Z][a-zA-Z]*" Then

然而,为了缩短这一点,我们可以使用[!charlist] 告诉操作员我们正在寻找不在提供范围内的东西。换句话说,我们可以使用:

If str Like "[!0-9][!0-9][!0-9][!0-9]*" Then

当您的字符串包含除字母数字字符之外的任何其他字符时,最后一种解决方案将不起作用。

【讨论】:

  • "[!0-9][!0-9][!0-9][!0-9]*" 并不适合检查“4 个字母”,任何带有没有数字会匹配它,例如“----”
  • @AlexandruHapco,非常正确。如果有“特殊”字符,则它不起作用,但您需要上面的解决方案。
  • 我想我也Like这个解决方案+1。
  • @Plutian,我同意 100%,但是这些是 MS 所说的“模式中的字符列表”。它是内置的,并且可能已经看到它的创建者从 RegEx 模式中汲取灵感,因为它们非常相似。一个巨大的区别是*Like 中用于任意数量的字符。在RegEx 中,它用于检查它之前定义的模式的零个或多个匹配项。
  • 为了艺术和除了问题*“可以在没有 RegEx 的情况下完成吗?”* 我演示了如何使用 FilterXML() 函数作为替代 :-)
【解决方案4】:

使用FilterXML 函数的方法

WorksheetFunction FilterXML() 已添加到 ►Excel 2013 中,允许为给定的 XML 文档指定任何 XPath 搜索字符串,该文档不必是本地保存的文件(需要 @987654323 @函数),但可以是格式良好打开和关闭节点中的字符串,即我们的测试字符串,带有一些简单的节点添加(部分类似于html结构)。

调用示例

Sub TextXML()
Dim myString As String
myString = "ABCD blah"
If check(myString) Then
   'DO STUFF
   Debug.Print "okay"
Else
   Debug.Print "oh no"
End If
End Sub

帮助功能

Function check(ByVal teststring As String) As Boolean
    Const s As String = Chr(185)  ' unusual character, e.g. Chr(185): "¹"
    On Error GoTo oops
    If Len(WorksheetFunction.FilterXML("<all><i>" & teststring & "</i></all>", "//i[substring(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','" & _
       String(26, s) & "'),1,4)='" & String(4, s) & "']")) > 0 Then check = True
    Exit Function
oops:
    Err.Clear
End Function

tl;tr - 如何在 2013 年之前的 Excel 版本中使用 VBA

为了艺术,通过 XMLDOM 方法使用 XPath 的经典方式:

调用示例

Sub TextXML2()
Dim myString As String
myString = "ABCD blah"

If check2(myString) Then
   'DO STUFF
   Debug.Print "okay"
Else
   Debug.Print "oh no"
End If
End Sub

帮助功能

Function check2(ByVal teststring As String) As Boolean
' Purpose: check if first 4 characters of a test string are upper case letters A-Z
  ' [0] late bind XML document
    Dim xDoc As Object
    Set xDoc = CreateObject("MSXML2.DOMDocument.6.0")
  ' [1] form XML string by adding opening and closing node names ("tags")
    teststring = "<all><i>" & teststring & "</i></all>"
  ' [2] load XML
    If xDoc.LoadXML(teststring) Then
      ' [3a] list matching item(s) via XPath
        Dim myNodeList As Object
        Set myNodeList = xDoc.SelectNodes(XPath())
            'Debug.Print teststring, " found: " & myNodeList.Length
      ' [3b] return true if the item matches, i.e. the list length is greater than zero
        If myNodeList.Length > 0 Then check2 = True
    End If

End Function

Function XPath() As String
' Purpose: create XPath string to get nodes where the first 4 characters are upper case letters A-Z
' Result: //i[substring(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹'),1,4)="¹¹¹¹"]
  ' get UPPER case alphabet
    Const ABC     As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  ' define replacement string consisting of an unusual character repeated 26 times
    Const UNUSUAL As String = "¹"       ' << replace by your preferenced character
    Dim replacement As String: replacement = String(Len(ABC), UNUSUAL)
    'return XPath string
    XPath = "//i[substring(translate(.,'" & ABC & "','" & replacement & "'),1,4)=""" & String(4, UNUSUAL) & """]"
End Function

【讨论】:

    【解决方案5】:

    要测试几个字符(在这种情况下是前 4 个字母),您始终可以执行以下操作:

    If Not (Mid(string, 1, 1) Like "#" And Mid(string, 2, 1) Like "#" _ 
        And Mid(string, 3, 1) Like "#" And Mid(string, 4, 1) Like "#") Then  
        ' DO STUFF
    End If
    

    当使用 Like 运算符时,键入的内容要多一些,但那又如何呢?此外,您可以在循环中使用Select Case... 另一种选择是使用IsNumeric(Mid(string, i, 1)) 而不是Mid(string, i, 1) Like "#" 等。

    当然,这种方法对于 4 个字符仍然很实用,但不像 RegEx 那样灵活且不可扩展。

    【讨论】:

    • “与使用 Like 运算符相比,键入要多一些”。您让我感到困惑,因为您自己使用的是 Like 运算符。为什么不充分发挥它的潜力呢?你输入的比其他答案多=)。
    • @JvdV 确实,就像我在答案中所说的那样,更多的是打字。但是,假设您只对第 3 个和第 27 个字符感兴趣。这个解决方案很容易适应这个或任何其他“少数字符”的需要(现在缩短了两倍)。我想知道在这种情况下,“全部潜力”的解决方案将如何发挥作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    相关资源
    最近更新 更多