使用正则表达式在单个正斜杠上分割字符串

4

编辑:哇,感谢大家提供这么多建议,但我想要一个针对未来更复杂的使用场景的正则表达式解决方案。

我需要在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这样的网站上可以正常工作。

4个回答

7
您可以使用正则表达式匹配方法而不是分割方法。您需要匹配除/或双重//之外的任何字符,以获取所需的值。
下面是一个“包装”(即带有交替项)版本的正则表达式:
(?:[^/]|//)+

这里有一个演示

以下是更高效但可读性较差的代码:

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

请查看另一个演示

这是一个完整的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

调用子程序的方法如下:
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

1
哇,这太棒了,通过测试运行,它看起来正是我所需要的。我已经苦思冥想了半天。Match对我来说是一个新概念,所以我需要反向工程才能完全理解它。非常感谢!这将是非常有用的学习经验。 - Trm
如果您在为 VBA 调整其他包含 lookbehind 的正则表达式方面遇到其他问题,请寻找“lookbehind workaround”。请注意,几乎总是需要将模式的一部分转换为代码。使用符合 JavaScript 标准的在线正则表达式测试工具。至于拆分,它可以在大多数情况下被匹配替换,并且通常更易读。 - Wiktor Stribiżew
一个快速的问题。我现在记得我之前使用过类似的方法来迭代匹配,但是我得到的是匹配项而不是它们之间的值。例如:对于 intIndex = 1 To objMatch.Count(我只得到了斜杠),为什么在你的示例中它返回文本?这是否与“ For Each”语句有关? - Trm
你得到了一个斜杠,因为objMatch包含匹配项。这就是正则表达式的作用:匹配特定的文本模式。当你分割时,仍然会匹配一些(序列)字符,它们作为给定输入的分隔符。For Each只是帮助迭代匹配项。或者子匹配项,但是由于我建议的模式中没有捕获组,所以你不需要它们。 - Wiktor Stribiżew
希望您不介意我问一下,如果我想使用相同的逻辑,但也考虑到“and”这个词在逻辑中的情况怎么办?所以它将通过单词“and”来分割正斜杠和/或。我正在考虑使用负向先行断言,但似乎无法使其工作 (?!\sand)[^\/]+(?:\/\/[^\/]*)* - Trm
让我们在聊天中继续这个讨论。点击此处进入聊天室 - Trm

1
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"

谢谢您的建议,但我想知道是否有正则表达式解决方案可用。将来我可能需要更多动态分割,而替换函数就不太适用了。 - Trm

0

前往数据选项卡,然后选择“文本到列”选项。接着,选择“分隔符号”选项,再选择“其他”并输入您想要的任何分隔符号。


如何使“文本分列”函数仅在单斜杠(/)处拆分,而不是双斜杠(//)? - Olle Sjögren
=RIGHT(A1,LEN(A1)-FIND("",SUBSTITUTE(A1,"","",LEN(A1)-LEN(SUBSTITUTE(A1,"",""))))) - Ashwith Ullal
=如果错误(RIGHT(H15,LEN(H15)-SEARCH("|",SUBSTITUTE(H15,"/","|",LEN(H15)-LEN(SUBSTITUTE(H15,"/",""))))),"-") - Ashwith Ullal

0

使用“文本分列”功能可以实现。如果您想保留原始值,另一种选择是使用公式: 在B1中

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

在C1中

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接