在字符串中查找字符的位置

时间:2018-07-17 08:22:12

标签: vb.net

如何获取字符串中某些字符的位置?

示例:我的字符串=“你好,你在做什么”

,我想从应该返回位置编号4、13和17的字符串中返回 o 的位置。我已经尝试过 str.IndexOf ,但是它仅返回第一次出现的 o

这是我尝试过的:

    Dim str = "hello, what you doing"
    Dim dIndex = str.IndexOf("o")
    If (dIndex > -1) Then
        Console.WriteLine(dIndex.toString())
    End If

任何方法都可以。

我正在使用Visual Studio 2008。

4 个答案:

答案 0 :(得分:3)

根据建议,您可以循环调用IndexOf,并将startIndex指定为比最后检测到的索引多1的位置。这是您可以在内部使用的扩展方法:

Imports System.Runtime.CompilerServices

Public Module StringExtensions

    <Extension>
    Public Iterator Function IndexesOf(source As String, value As Char) As IEnumerable(Of Integer)
        Dim startIndex As Integer
        Dim index = source.IndexOf(value)

        Do Until index = -1 OrElse startIndex = source.Length
            Yield index

            startIndex = index + 1
            index = source.IndexOf(value, startIndex)
        Loop
    End Function

End Module

您可以用与IndexOf几乎相同的方式进行调用,例如获取所有索引的列表。

Dim str = "babbabbbabbbbab"

For Each index In str.IndexesOf("a"c)
    MessageBox.Show(index.ToString())
Next

由于该方法是迭代器,因此可以部分停止For Each循环,并且该方法将同时停止其Do循环。如果您想要可以访问任何方式的完整列表,请在结果上调用ToArrayToList。您还可以执行诸如调用Take(3)的操作,以仅获取前三个索引,等等。

如果您不想使用扩展方法,只需使用其中的循环,并使用找到的索引将Yield语句替换为其他动作即可。

编辑:

这是在VS 2008中可以使用的方法的一个版本,因为它不是迭代器或扩展方法:

Public Function IndexesOf(source As String, value As Char) As List(Of Integer)
    Dim startIndex As Integer
    Dim index = source.IndexOf(value)
    Dim indexes As New List(Of Integer)

    Do Until index = -1 OrElse startIndex = source.Length
        indexes.Add(index)

        startIndex = index + 1
        index = source.IndexOf(value, startIndex)
    Loop

    Return indexes
End Function

答案 1 :(得分:2)

缺少System.TextRegularExpressions程序集中的解决方案。
它应该现在或多或少都可以在Visual Studio 2008中使用。

Imports System.Text.RegularExpressions

Dim MyString As String = "hello, what you doing"
Dim pattern As String = "o"

Regex.Matches()返回匹配元素的集合。 Match class具有一些属性;其中Index属性,用于报告匹配元素的位置。
在这种情况下,CharString中的位置。

Dim Indexes As MatchCollection = Regex.Matches(MyString, pattern)

For Each Position As Match In Indexes
    Console.WriteLine(Position.Index)
Next

这大致相同。它直接生成一个包含匹配位置的整数数组:
我不确定这是否可以在VS 2008中使用。

Dim Indexes As Integer() = Regex.Matches(MyString, pattern).OfType(Of Match)().
                           Select(Function(m) m.Index).ToArray()



如安德鲁·莫顿(Andrew Morton)所建议,.Net Regex类用于其操作的有关特殊字符的注释(可以称为metacharacters)。这些符号主要是:
\, *, +, ?, ^, $,., #, |, {, [, (,) +空格(CharW(32))。

请参阅有关.Net Regex文字,运算符和构造的参考页:
Regular Expression Language

如果有这样的字符串会发生什么:
(只需将"o"更改为"."

Dim MyString As String = "hell., what are y.u d.ing"
Dim pattern As String = "."

由于在正则表达式中.符号用作通配符,可匹配任何字符,因此返回的Indexes列表将包含所评估字符串中所有字符的位置。

如果您事先知道必须包含/搜索特殊字符,则可以插入一个硬编码的转义符:

Dim pattern As String = "\."

在这种情况下,Indexes列表将包含3个匹配的元素。

但是,如果您事先不知道表示图案的字符的性质,则可以使用Regex.Escape()方法来转义可能最终出现的特殊字符。

Dim pattern As String = "."
pattern = Regex.Escape(pattern)

Indexes列表将包含3个匹配的元素。

与此处使用的单个字符相比,此方法可以应用于更复杂的图案。有关示例,请参见Regex.Escape()文档。

答案 2 :(得分:1)

使用linq:

Dim indices = str.Select(Function(s, i) New With {s, i}) _
                 .Where(Function(x) x.s = "o"c) _
                 .Select(Function(x) x.i)

答案 3 :(得分:1)

有一个overload of IndexOf,它的位置从此开始。

因此,一旦找到第一个匹配字符的位置,就可以告诉它继续从该位置开始寻找。

我在这里做了一个返回位置列表的函数。 (如果没有匹配项,则列表将为空。)

Option Strict On
Option Infer On

Module Module1

    Function IndexesOf(s As String, c As Char) As List(Of Integer)
        Dim positions As New List(Of Integer)
        Dim pos = s.IndexOf(c)
        While pos >= 0
            positions.Add(pos)
            pos = s.IndexOf(c, pos + 1)
        End While

        Return positions

    End Function

    Sub Main()
        Dim os = IndexesOf("hello, what you doing", "o"c)
        For Each pos In os
            Console.WriteLine(pos)
        Next

        Console.ReadLine()

    End Sub

End Module

输出:

  

4
  13
  17