【问题标题】:Regex pattern matching for this, that or the other正则表达式模式匹配这个,那个或其他
【发布时间】:2023-03-17 22:14:02
【问题描述】:

我想解决一个问题:

对于可以是以下任何变体的文本字符串,我应该采取哪些步骤来提取我需要的信息?

  1. P09876-01-TP02-005-L-1087-315-802-105-99
  2. P09876-01-TP02-005-L-1087-315-802-105
  3. P09876-01-TP02-005-L-1087-315-802
  4. P09876-01-TP02-005-L-1087-315
  5. P09876-01-TP02-005-L-1087

我需要返回字符串 -L- 部分右侧的值。

我已经有了以下模式:

(\w{1}\d{5,}-\d{1,}-\w{2,}\d{2,}-\d{3,}-\w-)(\d{1,})-(\d{1,})-(\d{1,})-(\d{1,})-(\d{1,})|(\w{1}\d{5,}-\d{1,}-\w{2,}\d{2,}-\d{3,}-\w-)(\d{1,})-(\d{1,})-(\d{1,})-(\d{1,})|(\w{1}\d{5,}-\d{1,}-\w{2,}\d{2,}-\d{3,}-\w-)(\d{1,})-(\d{1,})-(\d{1,})|(\w{1}\d{5,}-\d{1,}-\w{2,}\d{2,}-\d{3,}-\w-)(\d{1,})-(\d{1,})|(\w{1}\d{5,}-\d{1,}-\w{2,}\d{2,}-\d{3,}-\w-)(\d{1,})

在我输入时考虑一下,我是否可以简单地检查上述模式返回的组号,然后将这些组值视为group(1), group(2), group(n) 等?

【问题讨论】:

  • 这些是单独的字符串,对吧?并且您拥有的正则表达式将它们全部“吃掉”为 1 个字符串。您是否只需要-L-(.*) 并获得第 1 组值?
  • 您是否还需要在大文本或字符串列表中找到与任何这些模式匹配的字符串?或者您处理的所有字符串都匹配其中一种格式,而您只需要识别这些片段?
  • {1} 是多余的,可以去掉;它只会弄乱regex{1,}+ 相同(如果您使用的语言或工具支持);改用+ 使regex 更具可读性
  • 你在哪里使用正则表达式?工具/编程语言是什么?
  • @stribizhev:VB.NET 是语言,Visual Studio Express 2015 是 IDE - 是的,它们是单独的字符串。

标签: .net regex vb.net pattern-matching


【解决方案1】:

在 VB.NET 中,为此使用正则表达式是没有意义的:

Dim str20 As String = "P09876-01-TP02-005-L-1087-315-802-105-99"
Dim idx20 As Integer = str20.LastIndexOf("-L-")
Dim result20 As String = str20
If idx20 > -1 Then
   result20 = str20.Substring(idx20 + 3)
   Dim splts = result20.Split("-"c)
End If

结果:

【讨论】:

  • 谢谢!当我在下面回复@ClasG 时,我确实需要分解字符串 -L- 部分后面的数字组
  • -分割找到的匹配:splts包含5个元素,你可以用它们来初始化你拥有的任何类。
  • 那太好了@stribizhev,谢谢。假设我有另一个没有 -L- 的变体,例如:P09876-01-TP04-003-220,其中我需要在字符串的 TP04-003 部分之后拆分所有内容,然后呢?
  • 你怎么知道是TP04-003之后的?实际的规格/要求是什么?无论如何,在这种情况下,您有一个 - 分隔字符串。使用Split,然后分析结果数组中的元素数量,并根据我猜的那个数字进行进一步的分配,也许,如果输入也包含-LIf str20.Contains("-L-") Then // proceed as above Else // just use Split End If.
【解决方案2】:

如果你想要的只是 L 值,你只需要得到-L-(\d+)。它获取 -L- 之后的数值作为第 1 组。或者如果 L 值是 -L- 之后的所有内容,如 stribizhev 所说 -L-(.*)

编辑:要将以下所有内容作为组,请尝试-L-(\d+)(-\d*)?(-\d*)?(-\d*)?(-\d*)。这将为您提供以下所有数字作为第 1、2、3 组...

问候

【讨论】:

  • 当我从这个或那个模式之一获得匹配时,我需要抓住后面的组 - 如果我以上面列表中的第一项为例,它会分解为 {Projectinfo }-{PartNum-Family}-{L-or-R}-{DimensionA}-{DimensionB}-{DimensionC}-{DimensionD}
  • @AlexF1980 - 见编辑。
  • 由于可选的(-\d*)?s 组将全部搞砸。我认为正则表达式在这里不是一个好方法。
【解决方案3】:

我不完全确定您搜索的来源是什么。我了解您正在寻找“L”之后的值。但是所有的字符串都遵循这种格式吗?假设使用的是这样,那么使用纯正则表达式你可以做类似的事情:

[^L\n]+L-(\d+)-?(\d+)?-(\d+)?-(\d+)?-(\d+)?

第一部分涵盖“L”之前的所有内容,不包括新行。第一个数字系列之后的部分是可选的(因此是“?”)。

【讨论】:

    【解决方案4】:

    FWIW,这是我的最终解决方案:

    ''' <summary>
    ''' Gets the dimension value from the part number
    ''' </summary>
    ''' <param name="PartNumString">the part number to search</param>
    ''' <param name="GroupNum"></param>
    ''' <returns></returns>
    ''' <remarks>This actually needs to do two things, one is to decide what the pattern is dependant on the Dimension we are searching for, the second is to find the correct group from the matches</remarks>
    Private Function GetDimensionValueFromPartName(PartNumString As String, GroupNum As Integer) As String
        Dim result As String = String.Empty
        Dim pattern As String = "(\w*\d*-\d*-\w*\d*-\d*-\w-)(\d*)-(\d*)-(\d*)-(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-\w-)(\d*)-(\d*)-(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-\w-)(\d*)-(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-\w-)(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-\w-)(\d*)|(\w*\d*-\d*-\w*\d*-\d*-)(\d*)-(\d*)-(\d*)-(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-)(\d*)-(\d*)-(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-)(\d*)-(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-)(\d*)-(\d*)|(\w*\d*-\d*-\w*\d*-\d*-)(\d*)|(\w*\d*-\d*-\w*\d*-\d*)|.*(\w*\d*-\d*-)(\d*)-(\d*)-(\d*)-(\d*)-(\d*)|.*(\w*\d*-\d*-)(\d*)-(\d*)-(\d*)-(\d*)|.*(\w*\d*-\d*-)(\d*)-(\d*)-(\d*)|.*(\w*\d*-\d*-)(\d*)-(\d*)|.*(\w*\d*-\d*-)(\d*)|.*(\w*\d*-\d*-\w-)(\d*)-(\d*)-(\d*)-(\d*)-(\d*)|.*(\w*\d*-\d*-\w-)(\d*)-(\d*)-(\d*)-(\d*)|.*(\w*\d*-\d*-\w-)(\d*)-(\d*)-(\d*)|.*(\w*\d*-\d*-\w-)(\d*)-(\d*)|.*(\w*\d*-\d*-\w-)(\d*)"
        Dim Dimensionregex As Regex = New Regex(pattern, RegexOptions.IgnoreCase)
        Dim match As Match = Dimensionregex.Match(PartNumString)
        Dim matchcount As Integer = 0
        Do While match.Success
            matchcount += 1
            Console.WriteLine("Match" & matchcount)
            Dim MatchStart As Integer = 0
            For index = 0 To match.Groups.Count
                If Not match.Groups(index).Value.Contains(PartNumString) And Not match.Groups(index).Value = String.Empty Then
                    MatchStart = index
                    Exit For
                End If
            Next
            If Not match.Groups(MatchStart + GroupNum).Value = String.Empty Then
                result = match.Groups(MatchStart + GroupNum).Value
            Else
                result = "-"
            End If
    
            match = match.NextMatch()
        Loop
        Return result
    End Function
    

    感谢您提出建议或改进。 (是的,这个模式现在非常长!)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      相关资源
      最近更新 更多