Stefan Đorđević
Stefan Đorđević

Reputation: 595

Regex matching first occurrence only?

This is the problem:

Code:

Dim findtext As String = "(?<=<hello>)(.*?)(?=</hello>)"
Dim myregex As String = TextBox1.Text
Dim doregex As MatchCollection = Regex.Matches(myregex, findtext)
MsgBox(doregex(0).ToString)

TextBox1:

<hello>1</hello>
<hello>2</hello>
<hello>3</hello>

So, when i run the code, it shows MsgBox with 1. Why only 1? Why not 2 and 3?

I added ? to .*, but it's still the same.

Upvotes: 0

Views: 122

Answers (3)

Xen
Xen

Reputation: 164

The MatchCollection contains multiple items but you are only retrieving the first one with doregex(0). Use a loop to get to the others:

Dim doregex As MatchCollection = Regex.Matches(myregex, findtext)
For Each match As Match In doregex
    MsgBox(match.ToString)
Next

EDIT:

To combine the values, append them to a String within the loop before you use it:

Dim doregex As MatchCollection = Regex.Matches(myregex, findtext)
Dim matches As String = ""  ' consider StringBuilder if there are many matches
For Each match As Match In doregex
    matches = matches + match.ToString + " " 
Next

MsgBox(matches)

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627126

Use LINQ:

Dim text_box_text = "<hello>1</hello>" & vbLf & "<hello>2</hello>" & vbLf & "<hello>3</hello>"
Dim findtext As String = "(?<=<hello>)(.*?)(?=</hello>)"
Dim my_matches_1 As List(Of String) = System.Text.RegularExpressions.Regex.Matches(text_box_text, findtext) _
                                     .Cast(Of Match)() _
                                     .Select(Function(m) m.Value) _
                                     .ToList()
MsgBox(String.Join(vbLf, my_matches_1))

enter image description here

Also, with this code, you do not need to use the resource-consuming lookarounds. Change the regex to

Dim findtext As String = "<hello>(.*?)</hello>"

and use .Select(Function(m) m.Groups(1).Value) instead of .Select(Function(m) m.Value).

Upvotes: 0

Abdellah OUMGHAR
Abdellah OUMGHAR

Reputation: 3745

Because you show only the first item in MatchCollection , you can use For Each loop to show all items like this :

For Each item In doregex
    MsgBox(item.ToString)
Next

You can combine items with many way, belows one of them :

Dim result As String = String.Empty
For Each item In doregex
    result = String.Format("{0} {1}", result, item)
Next
MsgBox(result)

Upvotes: 1

Related Questions