如何获取字符串中某些字符的位置?
示例:我的字符串=“你好,你在做什么”
,我想从应该返回位置编号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。
答案 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
循环。如果您想要可以访问任何方式的完整列表,请在结果上调用ToArray
或ToList
。您还可以执行诸如调用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
属性,用于报告匹配元素的位置。
在这种情况下,Char
在String
中的位置。
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()
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