2016-06-04 2 views
0

Итак, это проблема:Regex подходит только для первого появления?

Код:

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> 

Так что, когда я запускаю код, он показывает MsgBox с 1. Почему только 1? Почему не 2 и 3?

Я добавил ? в .*, но он все тот же.

+0

вам нужно перебрать объект соответствия, чтобы найти все соответствия – rock321987

+0

Лучше использовать его с LINQ, все становится намного проще. –

+0

LINQ - это дерьмо, и @Xen уже сделал лучшее решение, не нужно его ненавидеть и предлагать мне, что делать, потому что вы не ответили на лучшее решение: P –

ответ

1

MatchCollection содержит несколько элементов, но вы только извлекаете первый из них с doregex(0). Используйте цикл, чтобы добраться до других:

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

EDIT:

Чтобы объединить значения, добавьте их в строку в цикле, прежде чем использовать его:

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 (совпадения)

+0

Кажется, работает, но может ли он объединить все их в один MsgBox вместо создания новых каждый раз, когда он совпадает? Спасибо –

+0

@ StefanĐorđević См. [String.Join] (https://msdn.microsoft.com/en-us/library/system.string.join%28v=vs.110%29.aspx). –

+0

Не могу получить его на 100%, но спасибо в любом случае, я сделал то, что мне нужно! <3 –

1

Поскольку вы показываете только первый элемент в MatchCollection, вы можете использовать For Each цикл, чтобы показать все элементы, как это:

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

Вы можете комбинировать элементы со многими образом, сильфонных один из них:

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

Да, работает очень хорошо, но может ли он объединить 1, 2 и 3 в один MsgBox вместо открытия нового для каждого? Спасибо –

+0

вы можете увидеть ответ! –

0

Использование 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

Кроме того, с помощью этого кода, вам не нужно использовать ресурсоемкие lookarounds. Измените регулярное выражение

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

и использовать .Select(Function(m) m.Groups(1).Value) вместо .Select(Function(m) m.Value).

Смежные вопросы