2013-02-25 1 views
2

У меня есть тупо простой вопрос для кого-то, но я не могу ответить сам. У меня есть шаблон регулярных выражений, который работает в двух разных онлайн-тестерах, один из которых основан на .net.Совместимость с Visual Basic .net Regex не работает - несмотря на работу с инструментом тестирования?

Однако здесь он не находит совпадений. Может ли кто-нибудь помочь? Цель состоит в том, чтобы отфильтровать прекрасную страницу читов F #, чтобы она была доступна для печати :).

Я наставляю своего младшего брата, он на четвертой неделе учится программировать - это его функция, и я признаюсь, что это сильно меня озадачило! Любая помощь, за которую я был бы очень благодарен!

Public Function FindCode(input As String) 
    Dim pattern As String = "(?m)(<pre>)(.+)(<\/pre>)\B" 
    Dim output As New Dictionary(Of Integer, String) 
    Dim count As Integer 

    For Each match As Match In Regex.Matches(input, pattern) 
     output.Add(count, match.Value) 
     count += 1 
    Next 
Return output.count 
End Function 

У меня нет исключений, у меня нет совпадений.

Пример может быть

Some random markup <pre> and this stuff in the middle is what I'm after </pre> and there </pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags </pre> 

Таким образом, мы будем использовать группы, возможно перечислить все элементы между заранее/предварительно тегами.

Спасибо за такие быстрые ответы!

+0

Пожалуйста, разместите текст, который вы обрабатываете, чтобы соответствовать, ожидаемым результатам и фактическим результатам. –

+0

Бросает исключения – c0dem0nkey

+0

@JonSkeet Хорошая точка Джона, добавили. О, просто чтобы ползать ... Недавно я получил ваш последний C# In Depth E-Book. Хороший! У вашего предыдущего есть блестящее описание закрытия, которое повлияло на мое программирование с тех пор. –

ответ

1

Во-первых, я пробовал выражение, которое вы предоставили с помощью Expresso, а затем в LinqPad - обе вернули целую строку, которая не соответствует вашим требованиям. Я вижу 2 вопроса, почему она не показывает желаемый результат:

  1. Самого регулярное выражение
  2. Проблемы в примере строке (теги не попарно, т.е.каждый <pre> должен быть закрыт </pre>)

Кроме того, я предлагаю некоторые улучшения кода:

  1. Изменить способ вы соответствия (пример ниже использует Regex варианты, и позволяет группировать)
  2. Добавить тэгу в качестве параметра, добавьте параметр, чтобы разрешить включение или исключение из тегов
  3. Возвращаемых коллекция вместо значения счетчика
-

Взгляните на код, он отлично работает (я добавил некоторые дополнительные, закомментированные .Dump() заявления для LinqPad в случае, если вы хотите распечатать значения для отладки):

Public Function FindCode(input As String, tagName as string, includeTags as boolean) 
    Const grpName as string = "pregroup" 
    Dim pattern As String = "(<"+tagName+">)(?<"+grpName+">(\s|\w|')+)(</"+tagName+">)" 
    Dim output As New Dictionary(Of Integer, String) 
    Dim count As Integer 

    Dim options as RegexOptions = RegexOptions.IgnoreCase _ 
      or RegexOptions.IgnorePatternWhitespace _ 
      or RegexOptions.MultiLine or RegexOptions.ExplicitCapture 
    ' options.Dump("options") 
    Dim rx as Regex = new Regex(pattern, options) 
    For Each m As Match In rx.Matches(input) 
     Dim val as string=nothing 
     if (includeTags) 
      val = m.Value 
     else 
      if(m.Groups(grpName).Success) 
       val = m.Groups(grpName).Value 
      end if 
     end if 
     if not (val is nothing) 
      ' val.Dump("Found #" & count+1) 
      output.Add(count, val) 
      count += 1 
     end if 
    Next  
    Return output 
End Function 

Что касается выражения:

  • Я использую (\s|\w)+ вместо .+, потому что она включает в себя только пробельные и буквенно-цифровых символов, а не скобки и, следовательно, не теги
  • экранирующих символов конфликтующие с специальные символы синтаксиса Regex с помощью \xnn (где пп шестнадцатеричного код символа) - обратите внимание: это не применимо здесь
  • Используйте имя группы, чтобы легко получить доступ к содержимому тегов

Что касается код Regex: Я добавил параметр includeTags, чтобы вы могли видеть разницу (false исключает их, true включает их). Обратите внимание, что вы всегда должны правильно устанавливать RegexOptions, так как это влияет на соответствие выражений.

Наконец, вот основной код:

Sub Main 
    dim input as string = "Some random markup <pre> and this stuff in the middle is what I'm after </pre> and there <pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags </pre>" 
    dim result = FindCode(input, "pre", false) 
    dim count as integer = result.Count() 
    Console.WriteLine(string.Format("Found string {0} times.", count)) 
    Console.WriteLine("Findings:") 
    for each s in result 
     Console.WriteLine(string.format("'{0}'", s.Value)) 
    next 
End Sub 

Это Выведет:

Найдено строка 2 раза.

Выводы:

«много из них в одном файле»

«находит все теги»

Однако, есть еще один вопрос: почему это не первый <pre>...</pre> соответствует? Посмотрите на подстроку I'm after - она ​​содержит ', которая не соответствует, потому что она не является ни пробелом, ни буквенно-цифровым. Вы можете добавить его, указав (\s|\w|') в регулярном выражении, затем он отобразит все 3 строки.

+1

Ему не нужно скрывать '<' and '>' и '/'. Они не являются особым символом, если только в составном синтаксисе '(? )'. – Teejay

+0

@Teejay: Спасибо за подсказку, я попробую. – Matt

+0

@ Матт, как ни странно, он хотел получить доступ к группам; факт, который я удалил во время моего собственного поиска. Это довольно полный ответ Мэтт, спасибо тебе за то, что ты вложил. Я собираюсь применить его сегодня вечером. –

3

Я думаю, что проблема заключается в (.+) - это жадный по умолчанию, поэтому он подходит как можно больше, включая промежуточные </pre> частей.

Если вы изменили его на (.+?), вы должны получить несколько записей. Затем, чтобы найти текст в теге <pre>, вам нужно получить значение match.Groups[2]. ? делает .+неохотно - он соответствует как можно меньше символов.

Кроме того, неясно, что, кстати, должно достичь (?m).

(О, и, конечно, это вообще плохая идея для разбора HTML с использованием регулярных выражений ...)

+0

Ive, чтобы сыграть с этим в ближайшее время. Как я упоминал ниже, мой брат работал над прошлой ночью ... и он очень новый новичок в коде. iPad Я признаюсь в неопределенности на этом бит, пока я не сыграю с ним снова сегодня вечером. Я не мог заставить его Regex работать в VS, но он отлично поработал в Rubular, онлайн-тестере Regex. –

+0

Из любопытства у VB есть ограничение на возврат, как PCRE, когда вы используете неживые выражения? –

+0

@Jack: Не знаю, боюсь. (Но это было бы пределом в .NET, а не в VB.) –

1

Я получил правильный вывод (для данного регулярного выражения), один матч, содержащий:

<pre> and this stuff in the middle is what I'm after </pre> and there </pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags </pre>

Помимо тот факт, я полагаю, вы имели в виду <pre> (не </pre>) после того, как and there ...

Возможно, вы хотите использовать (.+?), потому что + по умолчанию жадный.


Кроме того, не ясно, почему (?m) и /B (и почему в конце, но не в начале).

+0

Regex был построен моим братом прошлой ночью в ответ на вызов, который я ему поставил. Он начал кодирование четыре недели назад, никогда не делал этого раньше и работает 12 часов в день в супермаркете. Я надеюсь помочь ему сменить работу. Ему 23 года. К сожалению, для него я еще не специалист по Regex :). Я протестировал оригинал на Rubular, поэтому я подозреваю, что его реализация тонко отличается. У меня здесь много ответов, чтобы прорваться сегодня вечером. Спасибо вам всем!! –

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