【问题标题】:Use Regex to Split Numbered List array into Numbered List Multiline使用正则表达式将编号列表数组拆分为编号列表多行
【发布时间】:2018-03-02 01:47:57
【问题描述】:

我正在尝试学习正则表达式来回答关于 SO 葡萄牙语的问题。

输入(单元格上的数组或字符串,所以.MultiLine = False)?

 1 One without dot. 2. Some Random String. 3.1 With SubItens. 3.2 With number 0n mid. 4. Number 9 incorrect. 11.12 More than one digit. 12.7 Ending (no word).

输出

 1 One without dot.
 2. Some Random String.
 3.1 With SubItens.
 3.2 With number 0n mid.
 4. Number 9 incorrect.
 11.12 More than one digit.
 12.7 Ending (no word).

我以为是使用Regex with Split,但我无法在 Excel 上实现示例。

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "plum-pear"
      Dim pattern As String = "(-)" 

      Dim substrings() As String = Regex.Split(input, pattern)    ' Split on hyphens.
      For Each match As String In substrings
         Console.WriteLine("'{0}'", match)
      Next
   End Sub
End Module
' The method writes the following to the console:
'    'plum'
'    '-'
'    'pear' 

所以阅读thisthisRegExr Website 与输入上的表达式 /([0-9]{1,2})([.]{0,1})([0-9]{0,2})/igm 一起使用。

得到以下结果:

有没有更好的方法来做这个?正则表达式是正确的还是更好的生成方式?我在 google 上找到的示例并没有启发我如何正确使用 RegEx 和 Split。

也许我对拆分函数的逻辑感到困惑,我想获得拆分索引,而分隔符字符串是正则表达式。

【问题讨论】:

  • 寻找 String.Replace(regex) - 和谷歌 BackReferences。我认为会类似于input.Replace("([0-9]*\.?[0-9]*)", "\0" + vbcrlf)
  • 每个项目是否总是以数字开头并以句点结尾?如果是这样,您可以使用更简单的模式:\d[ .\dA-Za-z]+?\.
  • 不,客场以数字开头。但是当他一个人的时候。可以没有句号。
  • 这是否意味着您的列表项不包含数字?您如何区分 4 作为项目符号项和 4 作为文本中的数字?
  • 好点。我想到了这一点,只是假设只有数字作为项目符号。但由于所有都以句号结尾,我想我可以让它以单词和句号结尾。我试图让它以数字开头并以单词和句点结尾。不成功。我正在阅读更多内容并进行一些尝试

标签: regex excel vba


【解决方案1】:

我可以让它以单词和句点结尾

使用

\d+(?:\.\d+)*[\s\S]*?\w+\.

请参阅regex demo

详情

  • \d+ - 1 位或多位数字
  • (?:\.\d+)* - 零个或多个序列:
    • \. - 点
    • \d+ - 1 位或多位数字
  • [\s\S]*? - 任何 0+ 个字符,尽可能少,直到第一个...
  • \w+\. - 1+ 个单词字符,后跟 .

这是一个示例 VBA 代码:

Dim str As String
Dim objMatches As Object
str = " 1 One without dot. 2. Some Random String. 3.1 With SubItens. 3.2 With Another SubItem. 4. List item. 11.12 More than one digit."
Set objRegExp = New regexp ' CreateObject("VBScript.RegExp")
objRegExp.Pattern = "\d+(?:\.\d+)*[\s\S]*?\w+\."
objRegExp.Global = True
Set objMatches = objRegExp.Execute(str)
If objMatches.Count <> 0 Then
  For Each m In objMatches
      Debug.Print m.Value
  Next
End If

注意

您可能要求匹配只在单词 + . 处停止,后跟 0+ 个空格和使用 \d+(?:\.\d+)*[\s\S]*?[a-zA-Z]+\.(?=\s*(?:\d+|$)) 的数字。

(?=\s*(?:\d+|$)) 正向前瞻要求在当前位置右侧紧跟 0+ 个空格 (\s*) 后跟 1+ 个数字 (\d+) 或字符串结尾 ($)。

【讨论】:

  • 谢谢!我试图让这个 RegEx 完全错误。使用^ 开始。我需要多学习,因为 RegEx 真的很有用。 ?=?: 是一些我在教程中没有看到的模式定义。再次感谢,回答很好解释
  • 刚刚更改为\d+(?:\.\d+)*[\s\S]*?[\D]+\.(?=\s*(?:\d+|$)),使用[\D] 而不是[a-zA-Z]。因为如果列表项以). 结尾,它将不起作用。
  • @danieltakeshi:注意\D 匹配任何非数字符号。您可能只想使用\d+(?:\.\d+)*[\s\S]*?\D\.(?=\s*(?:\d|$))。至于^,可以匹配字符串的开头(RegExp.Multiline = False),也可以匹配行的开头(RegExp.Multiline = True
  • @danieltakeshi 还有一个提示:如果字符串中没有换行符,[\s\S] 可以替换为.
【解决方案2】:

如果 VBA 的拆分支持后向正则表达式,那么这个可能会起作用,假设除了索引之外没有数字:

    \s(?=\d)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-06
    • 2020-08-07
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多