【问题标题】:Recognize block of data as one block using regex vba使用正则表达式 vba 将数据块识别为一个块
【发布时间】:2021-11-08 21:40:09
【问题描述】:

我正在尝试为以下文本创建模式

not included

 4680145876 
some text some text ffgg   
 30905102511638 
 1
other text other text

no included

这是我的尝试

^\s*\d{6,10}(?:\n(?!\s*\d{1,}\n).*){5}

我将在 VBA 中使用这样的模式 要突出显示的预期输出(五行)

468049876 
some text some text ffgg   
 30905102639638 
 1
other text other text

** 我在遇到问题时更新了问题 假设文本是这样的

not included

 468041476 
some text some text ffgg   
 31605102764638 
 1
other text other text
extra line
 416524332 
some text some text ffgg   
 30905103594638 
 1
other text other text
extra line
6354422
no included

这里我需要块来遵循顺序: 1- 6 到 12 位数字 2-然后一行中的一些文本 3- 数字等于 14 位 4- 1 到 3 位数字 5-文本(这是问题所在,因为该文本可能是两行而不是一行),我需要将该额外的行包含为一行 所以文本示例的输出

 468049876 
some text some text ffgg   
 30905103685638 
 1
other text other text extra line

 416524332 
some text some text ffgg   
 30905101497638 
 1
other text other text extra line

我的意思是文本将只包含两个块(每行五行)

  • 我正在使用这样的代码:

      With CreateObject("VBScript.RegExp")
      .Global = True: .MultiLine = True: .IgnoreCase = True
      .Pattern = sPattern
      If .Test(sInput) Then
          Set col = .Execute(sInput)
          For i = 0 To col.Count - 1
              x = Split(col.Item(i), vbLf)
              cnt = cnt + 1
              For j = LBound(x) To UBound(x)
                  a(i + 1, j + 1) = Application.WorksheetFunction.Clean(Trim(x(j)))
              Next j
          Next i
      End If
    

    结束

现在,当循环匹配项时,我得到了超过五个项目的变量 x。我预计只会得到五件物品。 每场比赛的第二组如何单独领取?

【问题讨论】:

  • 当您使用(?:\n(?!\s*\d{1,}\n) 时,您的模式不能跨越只有数字的匹配行,因此您将无法通过30905103300638

标签: excel regex vba


【解决方案1】:

在我看来,您应该在否定条件下检查 6-10 位数字,并且要匹配空格字节换行符,您可以使用 [^\S\r\n]

^( *\d{6,12} *\n.*\n *\d{14} *\n *\d{1,3} *)((?:\n(?! *\d{6,10} *$).+)*)

请参阅regex demo详情

  • ^ - 行首(记得使用)
  • ( - 第 1 组开始:
    • * - 零个或多个空格
    • \d{6,10} - 六到十位数
    • * - 零个或多个空格
    • \n.* - 一行
    • \n *\d{14} * - 一行 14 位数字,用零个或多个空格括起来
    • \n *\d{1,3} * - 一行一到三位数字,中间用零个或多个空格括起来
  • ) - 第 1 组结束
  • ((?:\n(?! *\d{6,10} *$).+)*) - 第 2 组:
    • (?: - 非捕获组的开始:
      • \n - LF 行结束
      • (?! *\d{6,12} *$) - 不紧跟零个或多个空格、六到十二位数字、零个或多个空格和行尾
      • .+ - 非空行(一个或多个除换行符之外的字符,尽可能多
    • )* - 分组结束,出现零次或多次。
  • ) - 第 2 组结束。

获得匹配项后,第 2 组包含最后一行行,因此您可以随意操作该文本,然后与第 1 组的值连接。

【讨论】:

  • 非常感谢。你能解释一下^ *\d{6,10} *(?:\n(?! *\d{6,10} *\n).+)* 的模式吗,因为它更简单而且对我有用?
  • @YasserKhalil 和另一个一样。只是一个空格匹配一个空格,\n 匹配一个换行符。
  • 我遇到了关于最后一行的问题,有时最后一行 other text other text 在两行上,我需要它是最后一行,因此该块应以 6 到 9 位数字开头并扩展为仅五行 .. 如果最后一行后跟一个新行上的文本,则将多余的行包含到最后一行。
  • @YasserKhalil 0 是第 1 组,1 是第 2 组。如果您需要在第 1 组和第 2 组中以不同方式处理换行符,请依次处理它们:For i = 0 To col.Count - 1 x = Split(col.Item(i).Submatches(0), vbLf).... 然后@ 987654346@
  • @YasserKhalil ^( *\d{6,12} *\n)(.*\n(?:.*\n)?)( *\d{14} *\n *\d{1,3} *)((?:\n(?! *\d{6,10} *$)[^\d\n]+)*)
猜你喜欢
  • 2022-12-07
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2022-01-27
  • 2019-01-06
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多