【问题标题】:Split string on single forward slashes with RegExp使用 RegExp 在单个正斜杠上拆分字符串
【发布时间】:2023-04-10 03:36:01
【问题描述】:

编辑:哇,感谢您提供这么多建议,但我希望有一个正则表达式解决方案,专门用于将来更复杂的使用。

我需要支持在 VBA Excel 中拆分文本字符串。我环顾四周,但解决方案要么适用于其他语言,要么无法在 VBA 中使用。

我只想用单斜杠分割单词:

text1/text2- split
text1//text2- no split
text1/text2//text3 - split after text1

我尝试使用 regexp.split 函数,但认为它在 VBA 中不起作用。当谈到模式时,我在想如下:

(?i)(?:(?<!\/)\/(?!\/))

但我在宏中执行搜索时也会出错,而它适用于以下网站:https://www.myregextester.com/index.php#sourcetab

【问题讨论】:

    标签: regex vba excel


    【解决方案1】:

    您可以使用 RegExp 匹配方法而不是拆分方法。您需要匹配除/ 或double // 以外的任何字符来获取您需要的值。

    这是正则表达式的“包装”(即交替)版本:

    (?:[^/]|//)+
    

    这是demo

    这里有一个更高效,但可读性较差:

    [^/]+(?://[^/]*)*
    

    another demo

    这是一个有效的 VBA 代码:

    Sub GetMatches(ByRef str As String, ByRef coll As collection)
    
    Dim rExp As Object, rMatch As Object
    
    Set rExp = CreateObject("vbscript.regexp")
    With rExp
        .Global = True
        .pattern = "(?:[^/]|//)+"
    End With
    
    Set rMatch = rExp.Execute(str)
    If rMatch.Count > 0 Then
        For Each r_item In rMatch
            coll.Add r_item.Value
            Debug.Print r_item.Value
        Next r_item
    End If
    Debug.Print ""
    End Sub
    

    调用sub如下:

    Dim matches As New collection
    Set matches = New collection
    GetMatches str:="text1/text2", coll:=matches
    

    以下是上述 3 个字符串的结果:

    1. text1/text2
     text1
     text2
    
    2. text1/text2//text3
     text1
     text2//text3
    
    3. text1//text2
     text1//text2
    

    【讨论】:

    • 哇,这太棒了,通过测试运行,它看起来正是我所需要的。头疼了半天。 Match对我来说是一个新概念,所以我需要进行逆向工程才能完全理解它。非常感谢!这将是非常有用的学习经验。
    • 如果您在为包含后视的 VBA 调整其他正则表达式时遇到其他问题,请查找“后视解决方法”。请注意,几乎总是需要将模式的一部分转换为代码。使用符合 JavaScript 的在线正则表达式测试器。至于拆分,大部分情况下可以用匹配来代替,通常可读性要好得多。
    • 一个简单的问题。我现在记得我以前使用类似的方法来遍历匹配项,但我得到的是匹配项而不是它们之间的值。示例:对于 intIndex = 1 到 objMatch.Count (我只返回斜线),您的示例如何返回文本?是不是一定要做“For Each”语句?
    • 你有一个斜线,因为objMatch 包含匹配项。这就是正则表达式的用途:匹配特定的文本模式。拆分时,您仍然匹配一些(序列)字符,这些字符用作给定输入的分隔符。 For Each 只是帮助迭代匹配。或子匹配,但您不需要它们,因为您没有我建议的模式中的捕获组。
    • 我希望你不介意问,但如果我想使用相同的逻辑,还要考虑逻辑中的“和”字?所以它会拆分正斜杠和/或单词“and”。我正在考虑使用负面展望,但似乎无法使其工作(?!\sand)[^\/]+(?:\/\/[^\/]*)*
    【解决方案2】:
    Public Sub customSplit()
        Dim v As Variant
    
        v = Split("text1/text2//text3", "/")
        v = Replace(Join(v, ","), ",,", "//")
    
        Debug.Print v   '-> "text1,text2//text3"
    End Sub
    

    Replace(Replace("text1/text2//text3", "/", ","), ",,", "//")   '-> "text1,text2//text3"
    

    【讨论】:

    • 感谢您的建议,但我想知道是否有可用的正则表达式解决方案。将来我可能需要更多的动态拆分,替换功能不会只是削减它。
    【解决方案3】:

    转到“数据”选项卡,然后转到“文本到列”选项。稍后,选择“分隔”选项,然后选择“其他”并输入您想要的任何分隔符。

    【讨论】:

    • 如何让 Text To Columns 函数只拆分单斜杠 (/) 而不是双斜杠 (//)?
    • =RIGHT(A1,LEN(A1)-FIND("~",SUBSTITUTE(A1,"\","~",LEN(A1)-LEN(SUBSTITUTE(A1,"\" ,"")))))
    • =iferror(RIGHT(H15,LEN(H15)-SEARCH("|",SUBSTITUTE(H15,"/","|",LEN(H15)-LEN(SUBSTITUTE(H15," /",""))))),"-")
    【解决方案4】:

    文本到列将起作用。如果要保留原始值,另一种选择是使用公式: 在B1

    =left(a1,find(":",a1)-1) 
    

    在 C1 中

    =mid(a1,find(":",a1)+1,len(a1))
    

    【讨论】:

      猜你喜欢
      • 2015-12-14
      • 1970-01-01
      • 2014-09-04
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      相关资源
      最近更新 更多