Страница: 1 | 2 | 3 |
Вопрос: Вопрос по поводу обработки html тегов
Добавлено: 31.10.06 01:49
Автор вопроса: Invise
Ответы
Всего ответов: 38
Номер ответа: 31
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #31
Добавлено: 05.11.06 21:13
Вот только не InStr и не Mid
Вообще я уверен что код, написаный специально для обработки конкретного рег. выражения будет работать быстрее чем само регулярное выражение.
Только писать код за 20 WMZ не буду
Номер ответа: 32
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #32
Добавлено: 05.11.06 23:00
Именно поэтому я и сказал, что .. цитирую:
Но по сути это достаточно серьезные тормоза, регэкспы работаю на 3 (условно) порядка быстрее
могу утверждать только одно, что работают они гораздо быстрее.. причем в десятки раз быстрее нежели искать вхождения через InStr, Mid и т.д
На что многоуважаемый товарищ Sharp глубоко возмутился:
Ты как-то неправильно ищешь. Регекспы не могут быть быстрее банального поиска подстроки и, тем более, взятия подстроки в принципе.
Вот я и прошу показать мне, ламеру бестолковому, как это делается с помощью InStr & Mid, чтобы это было быстрее регэкспа.
Номер ответа: 33
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #33
Добавлено: 06.11.06 03:50
Приведенный пример полностью реализует функциональность регекспа, результаты их работы целиком совпадают. Никто не говорил, что регекспы как-то сильно страшно сложно работают, по сути, именно тот код, который я написал, и выполняется, если не считать построение дерева анализа и работу общего конечного автомата для него.
20 WMZ и на C# я напишу тебе код и для твоего паттерна.
Зачем ты прицепился к InStr и Mid? Сравнение скорости регекспа вида для нахождения первой подмаски /(.){3}abc/ с функцией Mid(s, InStr(s, "abc"-3, 3) тебя устроит? Сможешь провести его самостоятельно? Справишься?
Номер ответа: 34
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #34
Добавлено: 06.11.06 05:27
Долго торговался, я уже написал (бесплатно)
В принципе не совсем тот же регексп (я пытался сделать аналогично [a-zA-Z0-9_\-\.]+@([a-zA-Z0-9\-]+\.)+[A-Za-z]{2,4}). Так, в ряде случаев, когда e-mail'ы пересекаются вроде artyom@soobcha.org@soobcha.org@soobcha.org и прочих экзотических он отработает не совсем верно (не все match'ы обнаружит), но я не ставил цель сделать идеальный алгоритм - просто оценить скорость регекспа и обычного поиска.
Могу дополнить алгоритм и он будет работать аналогично поиску регулярным выражением Но только если у меня опять появится большое желание, а оно у меня появится нескоро
Но вцелом преимущества очевидны.
Тесты проводил на 20 кб случайно сгенерированого текста в котором на каждые 1000 символов вставлен один e-mail.
RegExp: 00:00:01.9041750
MyCode: 00:00:00.0078120
Вцелом результаты просто несравнимы...
Отметки 2 секунды мой код достигает на файле размером 100 мегабайт (по понятным причинам для регулярного выражения тест на аналогичном объеме данных не проводился)
Dim Result As New List(Of MyMatch)
Dim CurrentStart As Integer = 0
Dim CurrentLex As Integer = -1
Dim IsMatch As Boolean = False
Dim SubDomainLength As Integer
Dim IsEnd As Boolean = False
Dim ValidEnd As Integer = -1
Dim ValidLocalEnd As Integer = -1
For i As Integer = 0 To text.Length - 1
Dim C As Char = text(i)
If Not IsMatch OrElse CurrentLex = 0 Then
If (C >= "0"c AndAlso C <= "9"c) OrElse (C >= "A"c AndAlso C <= "Z"c) OrElse (C >= "a"c AndAlso C <= "z"c) OrElse C = "-"c OrElse C = "."c OrElse C = "_"c Then
If Not IsMatch Then
IsMatch = True
CurrentStart = i
ValidEnd = -1
CurrentLex = 0
End If
GoTo ok
End If
End If
If IsMatch AndAlso CurrentLex = 0 Then
If C = "@"c Then
CurrentLex = 1
GoTo ok
End If
End If
If IsMatch AndAlso CurrentLex = 1 OrElse CurrentLex = 2 Then
If (C >= "0"c AndAlso C <= "9"c) OrElse (C >= "A"c AndAlso C <= "Z"c) OrElse (C >= "a"c AndAlso C <= "z"c) OrElse C = "-"c Then
CurrentLex = 2
GoTo ok
End If
End If
If IsMatch AndAlso CurrentLex = 2 Then
If C = "."c Then
CurrentLex = 3
SubDomainLength = 0
IsEnd = True
GoTo ok
End If
End If
If IsMatch AndAlso CurrentLex = 3 OrElse CurrentLex = 4 Then
If (C >= "0"c AndAlso C <= "9"c) OrElse (C >= "A"c AndAlso C <= "Z"c) OrElse (C >= "a"c AndAlso C <= "z"c) OrElse C = "-"c Then
CurrentLex = 4
SubDomainLength += 1
If C = "-"c Then
IsEnd = False
Else
If SubDomainLength >= 2 AndAlso SubDomainLength <= 4 AndAlso IsEnd Then
ValidLocalEnd = i
Else
ValidLocalEnd = -1
End If
End If
GoTo ok
End If
End If
If IsMatch AndAlso CurrentLex = 4 Then
If C = "."c Then
If IsEnd AndAlso ValidLocalEnd <> -1 Then
ValidEnd = ValidLocalEnd
End If
IsEnd = True
ValidLocalEnd = -1
SubDomainLength = 0
CurrentLex = 3
GoTo ok
End If
End If
If IsMatch AndAlso IsEnd AndAlso ValidLocalEnd <> -1 AndAlso CurrentLex = 4 Then
Result.Add(New MyMatch(text.Substring(CurrentStart, ValidLocalEnd - CurrentStart + 1), CurrentStart))
IsMatch = False
GoTo ok
End If
If IsMatch AndAlso ValidEnd <> -1 AndAlso CurrentLex = 4 Then
Result.Add(New MyMatch(text.Substring(CurrentStart, ValidEnd - CurrentStart + 1), CurrentStart))
IsMatch = False
GoTo ok
End If
IsMatch = False
ok:
Next
If IsMatch AndAlso IsEnd AndAlso ValidLocalEnd <> -1 AndAlso CurrentLex = 4 Then
Result.Add(New MyMatch(text.Substring(CurrentStart, ValidLocalEnd - CurrentStart + 1), CurrentStart))
End If
If IsMatch AndAlso ValidEnd <> -1 AndAlso CurrentLex = 4 Then
Result.Add(New MyMatch(text.Substring(CurrentStart, ValidEnd - CurrentStart + 1), CurrentStart))
End If
Return Result
End Function
Номер ответа: 35
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #35
Добавлено: 06.11.06 05:31
Так и есть.. ламер бестолковый.. Brand только что показал код, который удовлетворяет условиям..
От обещаных 20 WMZ он отказался, а Sharp'у публично приношу свои извинения..
Номер ответа: 36
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #36
Добавлено: 06.11.06 05:32
Прошу прощения за GoTo - вместо них должны были стоят Continue For, но я чего-то подумал, что GoTo может быстрее работать, проверял, но забыл обратно вернуть
Номер ответа: 37
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #37
Добавлено: 06.11.06 05:38
Еще подумал - можно быстрее сделать, если перебрать текст, найти все "@" и уже от них анализировать правую и левую часть, удовлетворяет ли она условиям - меньше проверок будет наверное.
Номер ответа: 38
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #38
Добавлено: 06.11.06 15:50
Ну не совсем правильно отрабатывающий код я тоже мог бы быстро написать Но правильный будет работать ненамного дольше. Поиск @ будет быстрее работать, если их в тексте мало, а это может быть и не так.