【问题标题】:Split string on several words, and track which word split it where在几个单词上拆分字符串,并跟踪哪个单词将它拆分到哪里
【发布时间】:2015-04-10 22:44:30
【问题描述】:

我正在尝试根据单词数组拆分长字符串。例如:

单词:trying, long, array

句子:“我正在尝试根据单词数组拆分一个长字符串。”

结果字符串数组:

  • 我是
  • 正在尝试
  • 拆分一个
  • 字符串基于一个
  • 数组
  • 字数

同一个词可能有多个实例,因此有两个实例尝试导致拆分或数组,可能会发生。

在 .NET 中是否有一种简单的方法可以做到这一点?

【问题讨论】:

  • 你想分割这些词,并将它们作为结果数组的一部分吗?
  • 是的,拆分并保留它们,请参阅对您的答案的评论。

标签: regex vb.net string substring


【解决方案1】:

在结果中保留分隔符的最简单方法是使用Regex.Split method 并在 中使用alternation 构造模式。该组是将分隔符包含在结果中的关键,否则它将删除它们。该模式看起来像(word1|word2|wordN),括号用于分组。此外,您应该始终使用Regex.Escape method 对每个单词进行转义,以避免将它们错误地解释为正则表达式元字符。

我还建议阅读我对类似问题的回答(以及其他人的回答)以了解更多详情:How do I split a string by strings and include the delimiters using .NET?

由于我用 C# 回答了这个问题,这里有一个 VB.NET 版本:

Dim input As String = "I am trying to split a long string based on an array of words."
Dim words As String() = { "trying", "long", "array" }

If (words.Length > 0)
    Dim pattern As String = "(" + String.Join("|", words.Select(Function(s) Regex.Escape(s)).ToArray()) + ")"
    Dim result As String() = Regex.Split(input, pattern)

    For Each s As String in result
        Console.WriteLine(s)
    Next
Else
    ' nothing to split '
    Console.WriteLine(input)
End If

如果您需要修剪每个要拆分的单词周围的空格,您可以为模式添加前缀和后缀 \s* 以匹配周围的空格:

Dim pattern As String = "\s*(" + String.Join("|", words.Select(Function(s) Regex.Escape(s)).ToArray()) + ")\s*"

如果您使用的是 .NET 4.0,则可以将 ToArray() 调用放在 String.Join 方法中。

编辑:顺便说一句,您需要预先决定拆分的工作方式。它应该匹配单个单词还是其他单词的子字符串?例如,如果您的输入中包含单词 “belong”,则上述解决方案将拆分为“long”,从而产生 {"be", "long"}。这是想要的吗?如果不是,那么对模式的微小更改将确保拆分匹配完整的单词。这是通过用字边界\b 元字符包围模式来实现的:

Dim pattern As String = "\s*\b(" + String.Join("|", words.Select(Function(s) Regex.Escape(s)).ToArray()) + ")\b\s*"

\s* 根据我之前提到的修剪是可选的。

【讨论】:

  • 感谢您的回答,我在发布问题之前确实尝试过搜索,只是一定没有使用正确的术语。这应该很好用。
  • @Patricker 没问题。请阅读我的编辑以获得额外的考虑。
【解决方案2】:

你可以使用正则表达式。

(.*?)((?:trying)|(?:long)|(?:array))(.*)

如果匹配,会给你三个组:

  • 1) 任何拆分字的第一个实例之前的位。
  • 2) 拆分词本身。
  • 3) 字符串的其余部分。

您可以在 (3) 上继续匹配,直到匹配完为止。

我已经玩过这个,但我无法获得一个将在目标词的 all 实例上拆分的单个正则表达式。也许有更多正则表达式的人可以解释一下。

我假设 VB 支持正则表达式。如果没有,我建议使用其他语言。当然 C# 有正则表达式。

【讨论】:

  • 你的想法不错,但有一种更简单的方法可以实现这一点。有关此类示例,请参阅my response :) 顺便说一句,Regex 类是 .NET 基类库 (BCL) 的一部分,因此可用于 C# 和 VB.NET;这不是特定于语言的功能。
【解决方案3】:

你可以用“”分割, 而不是遍历单词,看看哪个单词包含在“拆分单词”数组中

【讨论】:

  • 这是个好主意,但标点符号不会引起问题吗?假设我的一个词是句子中的最后一个词,或者出现在逗号之前或引号之前/之后,那么它可能找不到它,因为它不完全是这个词。如果我尝试使用 string.contains,我想我最终会匹配非精确术语,比如“瘦”会匹配“思考”。
【解决方案4】:
    Dim testS As String = "I am trying to split a long string based on an array of words."

    Dim splitON() As String = New String() {"trying", "long", "array"}

    Dim newA() As String = testS.Split(splitON, StringSplitOptions.RemoveEmptyEntries)

【讨论】:

  • string.split 的问题在于它删除了它拆分的值。因此,如果我这样做,我拆分的所有单词都会从结果数组中丢失,但我需要它们在那里。生成的数组应该像我帖子中的示例一样,其中存在单词(斜体是重点)。
【解决方案5】:

类似的东西

    Dim testS As String = "I am trying to split a long string based on a long array of words."

    Dim splitON() As String = New String() {"long", "trying", "array"}

    Dim result As New List(Of String)
    result.Add(testS)

    For Each spltr As String In splitON
        Dim NewResult As New List(Of String)
        For Each s As String In result
            Dim a() As String = Strings.Split(s, spltr)
            If a.Length <> 0 Then
                For z As Integer = 0 To a.Length - 1
                    If a(z).Trim <> "" Then NewResult.Add(a(z).Trim)
                    NewResult.Add(spltr)
                Next
                NewResult.RemoveAt(NewResult.Count - 1)
            End If
        Next
        result = New List(Of String)
        result.AddRange(NewResult)
    Next

【讨论】:

    【解决方案6】:

    彼得,我希望以下内容适用于使用正则表达式按单词数组拆分字符串

    // Input
    String input = "insert into tbl1 inserttbl2 insert into tbl2 update into tbl3 
    updatededle into tbl4 update into tbl5";
    
    //Regex Exp
    String[] arrResult = Regex.Split(input, @"\s+(?=(?:insert|update|delete)\s+)",
    RegexOptions.IgnoreCase);
    
    //Output
    [0]: "insert into tbl1 inserttbl2"
    [1]: "insert into tbl2"
    [2]: "update into tbl3 updatededle into tbl4"
    [3]: "update into tbl5" 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多