当前位置: 首页 > 知识库问答 >
问题:

在双正斜杠和/或特定单词上使用正则表达式拆分字符串

司马高明
2023-03-14

我正在尝试通过双正斜杠和/或特定字符串(如“and”)拆分文本。

Example A:
text1 a/s // text2 a/b
text1 a/s and text2 a/b


Example B:
text1. // text2,// text3-
text1. and text2, and text3-
  • 示例A返回两个匹配项:text1 A/S text2 A/B
  • 示例B返回三个匹配项:text1。文本2、文本3-

我得到了一个非常有用的技巧:如何通过单个正斜杠拆分字符串:使用RegExp在单个正斜杠上拆分字符串,但试图找到一个排除两个正斜杠或一个字符串的解决方案,被证明是太有挑战性了。

如果有可能将两个示例合并为一个解决方案,则加分:

Example C:
text1 a/s // text2, and text3-

我希望只有与VBA兼容的RegExp解决方案。

共有1个答案

平和雅
2023-03-14

正如您所说,您已经有了一个工作解决方案,用于在带有regexp的单个正斜杠的拆分字符串中使用不同的拆分字符。该代码实际上并不拆分字符串,但它匹配除“/”之外的所有内容。然后,它返回集合中每个单独匹配的结果(是的,它最终被拆分)。

这里需要做的是匹配str中的每个字符,除非接下来的字符是//。我们可以用前瞻的方式来处理这件事。

只需通过以下操作更改代码中的模式:

.Pattern = "(?!$)((?:(?!//|\band\b).)*)(?://|and|$)"

或者,如果要为每个内标识修剪空格,请使用以下正则表达式:

.Pattern = "(?!$)((?:(?!\s*//|\s*\band\b).)*)\s*(?://|and|$)\s*"

虽然这也将匹配//,但它使用(group)来捕获实际的令牌。因此,您必须使用.submatches(0)(第一组反向引用的内容)将标记添加到集合中。

在代码中,不要添加coll.add r_item.value,而应使用:

coll.Add r_item.SubMatches(0)

注意:如果字符串有换行符,不要忘记使用.multiline=true设置rexp对象。

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
        .MultiLine = True
        .Pattern = "(?!$)((?:(?!\s*//|\s*\band\b).)*)\s*(?://|and|$)\s*"
    End With

    Set rMatch = rExp.Execute(str)
    If rMatch.Count > 0 Then
        For Each r_item In rMatch
            coll.Add r_item.subMatches(0)
        Next r_item
    End If
End Sub

这就是您可以在示例中调用它的方式:

Dim text As String
text = "t/xt1.//text2,and landslide/ andy  // text3-  and  text4"

'vars to get result of RegExp
Dim matches As New Collection, token
Set matches = New Collection

'Exec the RegExp --> Populate matches
GetMatches text, matches

'Print each token in debug window
For Each token In matches
    Debug.Print "'" & token & "'"
Next token
Debug.Print "======="

每个令牌都打印在即时窗口中。

  • 此代码是@stribizhev
  • 最初发布的代码的修改版本
't/xt1.'
'text2,'
'landslide/ andy'
'text3-'
'text4'
=======

您可能想知道这种模式是如何工作的。我试着用一个详细的描述来解释。为了做到这一点,让我们使用以下正则表达式,仅取模式的重要部分(其余部分并不重要):

((?:(?!//|\band\b).)*)(?://|and|$)

它可以很容易地分为两种结构:

>

  • 首先,子模式((?:(?!//\band\b).)*)是一个匹配每个令牌的组,反向引用我们要为每个匹配返回的文本。在vba中,使用.submatchs()返回组。让我们把它踩下来:
    • 内部表达式(?!//\band\b).首先进行检查,以确保后面没有拆分字符串(“//”或“”)。如果不是,则regex引擎匹配一个字符(注意末尾的点)。就是这样,它与我们捕获的令牌中允许的一个字符匹配。
    • 现在,它包含在(?:(?!//\band\b)中。)*要对它可以匹配的每个字符重复它,我们将获得令牌中的所有字符。这个构造是最接近while循环的构造。

      虽然后面没有拆分字符串,但获取下一个字符。

      例如:

      text1 a/s and text2 a/b//last
      ^        ^| |               [1]: 1st subpattern, captured in Matches(0).SubMatches(0)
      |--------|^-^
      |   1      2|               [2]: Split string, not captured but included in match
      |-----------|
            3                     [3]: The whole match, returned by Matches(0)
      
      
      For the second match, Matches(1).Value = " text2 a/b//"
                            Matches(1).Submatches(0) = " text2 a/b"
      


      模式的其余部分只是细节:

  •  类似资料:
    • 我正在尝试用单个反斜杠替换所有双反斜杠。我想将替换为。我以为python将视为一个反斜杠,将视为带有两个反斜杠的字符串。但是当我尝试时 因此,我尝试用原始字符串切换替换字符串: 这不是我需要的。所以我只尝试了原始字符串中的一个反斜杠:

    • 问题内容: 我想构建一个JS函数,将一个参数列表隐藏到有效路径中(因为我不确定路径的一部分是否带有斜杠) 这是功能: 使用的RegEx匹配了http://regexpal.com上的所有开始和结束斜杠和反斜杠,但是该功能无法正常工作(RegEx不匹配)。此外,Chrome指出 语法错误:无效的正则表达式:/()$ | ^()/:未终止的组 当我只使用RegEx 但是,使用RegEx 提前致谢! 狮

    • 问题内容: 我需要有关正则表达式的帮助:我正在尝试检查一个句子是否包含特定单词。 让我们以这个主题的标题为例: “正则表达式以查找字符串中的特定单词” 我需要查找它是否包含 if ,在这种情况下它是错误的。 我无法使用包含的方法,因为在这种情况下它将返回true( 如果为 * ic, 则为 spec * ) 我当时在考虑使用方法匹配,但我有点正则表达式。 基本上,匹配方法输入中的正则表达式需要指定

    • 问题内容: 我是regex的新手,我想做的是在特定条件下拆分String,但我不知道该怎么做。 这是样品/条件 我希望字符串被拆分,,,,,, 这可能吗? 问题答案: 如果 确实 需要使用正则表达式,则可能应该使用环顾四周机制,因为您不想 在 此字符 之前 或 之后 进行拆分。 输出:

    • 问题内容: 我没有JavaScript方面的丰富经验,但是我正在尝试创建一个标记系统,而不是使用or ,而是使用。 我该如何使用而不是。我尝试做并添加,但是失败了。 问题答案: 您可以这样逃避它。 或只使用indexOf

    • 问题内容: 我将如何拆分单词: 放入数组,这样我就可以得到: 与? 我很累,但这只是整个词 问题答案: 您还可以用作: 说明: