Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 | 3 |

 

  Вопрос: Вопрос по поводу обработки html тегов Добавлено: 31.10.06 01:49  

Автор вопроса:  Invise

Ответить

  Ответы Всего ответов: 38  

Номер ответа: 31
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #31 Добавлено: 05.11.06 21:13
- Будет использовать встроенные ф-и работы со строками InStr, Mid и т.д..

Вот только не InStr и не Mid :)

Вообще я уверен что код, написаный специально для обработки конкретного рег. выражения будет работать быстрее чем само регулярное выражение.

Только писать код за 20 WMZ не буду :)

Ответить

Номер ответа: 32
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #32 Добавлено: 05.11.06 23:00
Вот только не InStr и не Mid

Именно поэтому я и сказал, что .. цитирую:
Но по сути это достаточно серьезные тормоза, регэкспы работаю на 3 (условно) порядка быстрее

 могу утверждать только одно, что работают они гораздо быстрее.. причем в десятки раз быстрее нежели искать вхождения через InStr, Mid и т.д


На что многоуважаемый товарищ Sharp глубоко возмутился:
Ты как-то неправильно ищешь. Регекспы не могут быть быстрее банального поиска подстроки и, тем более, взятия подстроки в принципе.

Вот я и прошу показать мне, ламеру бестолковому, как это делается с помощью InStr & Mid, чтобы это было быстрее регэкспа.

Ответить

Номер ответа: 33
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #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
20 WMZ и на C# я напишу тебе код и для твоего паттерна

Долго торговался, я уже написал (бесплатно) :)

В принципе не совсем тот же регексп (я пытался сделать аналогично [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 мегабайт (по понятным причинам для регулярного выражения тест на аналогичном объеме данных не проводился)

    Function FindMatches(ByVal text As String) As List(Of MyMatch)
        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
Вот я и прошу показать мне, ламеру бестолковому, как это делается с помощью InStr & Mid, чтобы это было быстрее регэкспа.


Так и есть.. ламер бестолковый.. 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-сайт: sharpc.livejournal.com
 Профиль | | #38
Добавлено: 06.11.06 15:50
Ну не совсем правильно отрабатывающий код я тоже мог бы быстро написать :) Но правильный будет работать ненамного дольше. Поиск @ будет быстрее работать, если их в тексте мало, а это может быть и не так.

Ответить

Страница: 1 | 2 | 3 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам