Страницы: 1
RSS
Вопрос по регулярным выражениям в строке найти заменить
 
Добрый день

Нужно выдрать дату производства из текста ячейки
Дата производства обозначается по правилу 1979-1990
То есть 4 цифры дефис 4 цифры
Перед датой и после даты есть текст, и возможно тоже с дефисами

Можно ли использовать регулярные выражения для подобной автозамены?

Заранее спасибо
 
Что на что поменять-то нужно, пример приложите
 
Доброе время суток
Цитата
выдрать
- извлечь ;)
Цитата
автозамены
не находите что это между собой не очень то сбивается?
Шаблон для выражения будет
Код
\d{4}-\d{4}
или более жёстко, исходя из примера
Код
19\d{2}-19\d{2}

Успехов/
 
кнопка цитировния не для ответа [МОДЕРАТОР]

Согласен, условия сформулировал некорректно, прошу прощения
Есть ячейки типа "ТЕКСТ С СИМВОЛАМИ И ПРОБЕЛАМИ 1980-2001 ТЕКСТ С СИМВОЛАМИ И ПРОБЕЛАМИ"
Даты разные
Хочу через меню "заменить" (ctrl+H) заменить значение ячейки на 4 цифры по краям от тире

В каком то допотопном редакторе это работало так (вопрос - один символ, звездочка - любое количество символов )
найти *????-????*
заменить на ????-????
Но в этом примере будут взяты значения вокруг любого дефиса, а не дефиса между датами
 
Цитата
LVL написал: Что на что поменять-то нужно, пример приложите
Например так
AUDI 100   IV (A6 I) СД 1991-1997 СТ ЗАДН ДВ ОП   ПР ЗЛ
поменять на 1991-1997

дефис в тексте может быть не единственным
 
Цитата
поменять на 1991-1997
Может выделить из строки 1991-1997?
 
Excel не имеет фактически регулярных выражений, так небольшой набор символов - всё же не текстовый редактор. Я писал о применении udf-функции либо макроса, который используя объект регулярных выражений VBScript.RegExp, либо, в случае функции, возвращает текст по шаблону, либо, в случае макроса, заменяет существующее значение на текст по шаблону. На форуме это уже неоднократно обсуждалось.
 
grafgoro, нашёл на стороннем сайте (http://vdasus.com/2011/11/03/regulyarnye-vyrazheniya-v-excel/) - возможны ошибки... Тема очень интересная...
Код
Public Function RgxReplace(aregexp As String, astring As Range, areplace As String) As String
Dim re As RegExp
Set re = New RegExp
re.Pattern = aregexp
RgxReplace = re.Replace(astring, areplace)
End Function 
Нашёл лучше (http://vba.valemak.com/vba/regexp/replace/)
Код
'Поиск по регулярному выражению и замена.
                        Pattern As String, _
                        Replace As String, _
                        Optional Globa1 As Boolean = True, _
                        Optional IgnoreCase As Boolean = False, _
                        Optional Multiline As Boolean = False) _
                As String
     
    RegExpFindReplace = str 'Пока ничего не меняли
     
    If Not str Like "" And Not Pattern Like "" Then
     
        Dim RegExp As Object 'Для регулярного выражения
         
        Set RegExp = CreateObject("VBScript.RegExp")
        With RegExp
            .Global = Globa1 'Все совпадения или только первое?
            .IgnoreCase = IgnoreCase 'Регистр неважен?
            .Multiline = Multiline 'Игнорировать переносы строк?
            .Pattern = Pattern 'Регулярка
        End With
 
        'Найти/заменить
        On Error Resume Next
        RegExpFindReplace = RegExp.Replace(str, Replace) 
         
        Set RegExp = Nothing 'Очистка памяти
     
    End If
     
End Function
Изменено: Jack_Famous - 21.04.2016 14:27:20
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Код
Function Года(s As String)
    With CreateObject("vbscript.regexp")
        .Pattern = "19\d{2}-19\d{2}"
        .Global = True
        .IgnoreCase = True
        Года = .Execute(s)(0)
    End With
End Function
 
Kuzmich, здравствуйте и прошу прощения... Поясните пожалуйста по строке
Код
Года = .Execute(s)(0)
Это извлечь найденное, но что (0) означает? Заранее спасибо))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Execute возвращает массив совпадений(массив Matches). Массив начинается с нуля. Т.е.
Код
objMatches = .Execute(s)
Msgbox objMatches(0) 'первый элемент массива
Msgbox objMatches(1) 'второй элемент массива
'и т.д.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
The_Prist, спасибо большое! Получается, что практически всегда нужно "0" указывать  ;)  Продолжаю разбираться)))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Добрый день.
Спрошу раз тема - мне недавно нужно было в строке
"(123+456)+789+123"
заменить всё что в скобках или хотя бы "+" (но если он в скобках) на что угодно, чтоб позже разбить по плюсам в массив и получить 3 элемента.
Причём таких выражений в скобках может быть несколько, в любом порядке. Но так и не нашёл паттерн, обошлись...
Не подскажете регулярку на всякий случай?
 
Игорь, в рамках примера исходной строки, так
Код
Public Sub test()
     Dim pReg As Object
     Set pReg = CreateObject("VBScript.RegExp")
     pReg.Global = True: pReg.Pattern = "\(\d+\+\d+\)"
     Debug.Print pReg.Replace("(123+456)+789+(3456+2345)+123", "NAN")
End Sub

Успехов.
 
Андрей, спасибо! То что надо! Может ещё пригодится в том проекте.
 
добрый день,Hugo,если Вам надо,например вытащить фрагмент из скобок,можно использовать функцию в файл примере, типа example

Код
Function example(t$)
 With CreateObject("VBScript.RegExp"): .Pattern = "\((\d+\+\d+)\)\+\d+\+\d+": .Global = True
    example = .Execute(t)(0).Submatches(0)
 End With
End Function
Изменено: sv2013 - 21.04.2016 19:14:36
 
Игорь, похитил идею у тезки.
Сразу массив
Код
Public Sub test()
     Dim pReg As Object
     Set pReg = CreateObject("VBScript.RegExp")
     pReg.Global = True: pReg.Pattern = "(\(\d+\+\d+\)|\d+)"
     Set oMathes = pReg.Execute("(123+456)+789+(3456+2345)+123")
     ReDim a(0 To oMathes.Count)
     For Each x In oMathes
     a(i) = x: i = i + 1
     Next
'     Debug.Print pReg.Replace("(123+456)+789+(3456+2345)+123", "NAN")
End Sub
 
Ух, спасибо sv2013 (не знаю как звать :) ) и Андрей - пора изучить эти регулярки уже самому наверное :)
А то я и так пробовал, и эдак - всё не то получалось (и мануалы не помогли), хотя задача вроде простая - определить сколько всего слагаемых, считая то что в скобках за одно.
Сохраню примеры, спасибо ещё раз.
 
Только пришел, всем большое спасибо за ответы.
Жаль, я то надеялся что можно в меню "найти-заменить" прописать замены регулярными выражениями, без макросов
Буду изучать
 
Уважаемые форумчане! Функция на регулярках не хочет вытаскивать несколько строк через перенос строки))) как её поправить?...
Причём на сайте, для проверки регулярок работает отлично...  
Изменено: Jack_Famous - 26.04.2016 16:09:03
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Доброе время суток
Jack_Famous, а чего вы хотели добиться таким шаблоном "ОТД - полы<>.+" и вашим кодом? Метод RegEx.Execute возвращает коллекцию подстрок, каждая из которых, по смыслу, всё что начинается с "ОТД - полы<>" до тех пор пока опять не встретилось "ОТД - полы<>. Ну, вернул этот метод 3 объекта Match. Вы взяли значение первого из коллекции и вернули вашей udf-функцией - что не так?
Изменено: Андрей VG - 26.04.2016 18:28:53
 
Андрей VG, здравствуйте))) дело в том, что на сайте этот шаблон возвращает ВСЕ 3 значения, у Дмитрия The_Prist в его надстройке Multex тоже все 3 (правда у него на C#). А функция в файле только первое. Причём, если заменить шаблон на "ОТД - полы<>.+/s.+" (или что-то вроде того), то находит 2 (но для 1 выдаёт ошибку), если ещё увеличить, то находит 3 (но если есть только 1 или 2 выдаёт ошибку) и так далее. Пробовал что-то вроде "(ОТД - полы<>.)*", но тоже никак. Менял MultiLine на 1 - не помогает...
Функция из файла:
Код
Public Function RegExpExecute2(str$, ptrn$)
 
    With CreateObject("VBScript.RegExp")
            .Global = 1
            .IgnoreCase = 0
            .MultiLine = 0
            .Pattern = ptrn
            
RegExpExecute2 = .Execute(str)(0)

        End With
     
End Function
Изменено: Jack_Famous - 26.04.2016 20:18:15
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack_Famous написал:
у Дмитрия The_Prist в его надстройке Multex тоже все 3
То есть, прочитать, а главное понять, что пишет The_Prist чуть выше в #11, у вас не получилось?
Сделайте элементарный цикл по найденному
Код
For Each p In RegExp.Execute(sText)
    sOut = sOut & vbCrLf & p.Value
Next
 
Уважаемый Андрей VG, я не знаю VBA, поэтому и решаю только методом тыка и обращаюсь за помощью сюда на форум...
Пост №11 я читал и вынес оттуда:
Цитата
Получается, что практически всегда нужно "0" указывать
- так что я даже не понимаю, как применить ваш ответ в моём случае, т.к. он явно не для этой функции напрямую (переменных sOut и sText у меня нет). Попробовал изменить под свою - не вышло...
Код
Public Function RegExpExecute3(str$, ptrn$)

Dim p
 
    With CreateObject("VBScript.RegExp")
            .Global = 1
            .IgnoreCase = 0
            .MultiLine = 0
            .Pattern = ptrn
End With
            
For Each p In RegExp.Execute(str)

    RegExpExecute3 = RegExpExecute3 & vbCrLf & p.Value
    
Next
     
End Function

'For Each p In RegExp.Execute(sText)
'    sOut = sOut & vbCrLf & p.Value
'Next
Изменено: Jack_Famous - 26.04.2016 21:02:38
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Код
Public Function RegExpExecute3(str$, ptrn$)

    Dim p

    With CreateObject("VBScript.RegExp")
        .Global = 1
        .IgnoreCase = 0
        .MultiLine = 0
        .Pattern = ptrn

        For Each p In .Execute(str)
            RegExpExecute3 = RegExpExecute3 & vbCrLf & p.Value
        Next
    End With

End Function
 
Hugo, я был в паре переборов)))) спасибо вам огромное!!!  :idea: ))) а также всем остальным, кто принимал участие - получилась шикарная функция  8)
Всем добра  :D
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
grafgoro, Нашли решение? Может, чем помогу? :)
There is no knowledge that is not power
 
Доброго утра уважаемые пользователи! Подскажите, как побороть тот факт, что эта функция добавляет разделитель перед ПЕРВЫМ или ЕДИНСТВЕННЫМ найденным?...
Код
Public Function RegExpExecute(str$, ptrn$, delim$, Glob$, IgnCase$, MulLine$)

    If delim = "перенос" Then delim = Chr(10)
    If delim = "" Then delim = " "
    
    Dim p
 
    With CreateObject("VBScript.RegExp")
        .Global = Glob
        .IgnoreCase = IgnCase
        .MultiLine = MulLine
        .Pattern = ptrn
 
        For Each p In .Execute(str)
        
'        RegExpExecute = "" (если нужно только одно значение)

        RegExpExecute = RegExpExecute & delim & p.Value
        Next
        
    End With
 
End Function
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Доброе время суток
Просто добавьте проверку результата
Код
Public Function RegExpExecute(str$, ptrn$, delim$, Glob$, IgnCase$, MulLine$)
 
    If delim = "перенос" Then delim = Chr(10)
    If delim = "" Then delim = " "
     
    Dim p As Object, sOut As String
    sOut = ""
    With CreateObject("VBScript.RegExp")
        .Global = Glob
        .IgnoreCase = IgnCase
        .MultiLine = MulLine
        .Pattern = ptrn
  
        For Each p In .Execute(str)
            If Len(sOut) = 0 Then
                sOut = p.Value
            Else
                sOut = sOut & delim & p.Value
            End If
        Next
    End With
    RegExpExecute = sOut
End Function

Успехов.
 
Андрей VG, спасибо Вам огромное, Андрей!!!  :idea: 8)   Прекрасная и универсальная UDF получилась!)))) Постараюсь самостоятельно применить такого рода проверку где-нибудь ;)  Всем добра и успехов! )))
Код
'Извлечение с помощью регулярных выражений
'Использован код автора: Kuzmich
'Авторы рабочих версий UDF: Андрей VG, Hugo
'Тема на форуме: http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=77124&TITLE_SEO=77124-vopros-po-regulyarnym-vyrazheniyam-v-stroke-nayti-zamenit&MID=647893#message647893
'==================================================================================================================================================================================================
Public Function RegExpExecute(str$, ptrn$, delim$, Glob$, IgnCase$, MulLine$)
  
    If delim = "перенос" Then delim = Chr(10)
    If delim = "" Then delim = " "
      
    Dim p As Object, sOut As String
    sOut = ""
    With CreateObject("VBScript.RegExp")
        .Global = Glob
        .IgnoreCase = IgnCase
        .MultiLine = MulLine
        .Pattern = ptrn
   
        For Each p In .Execute(str)
            If Len(sOut) = 0 Then
                sOut = p.Value
            Else
                sOut = sOut & delim & p.Value
            End If
        Next
    End With
    RegExpExecute = sOut
End Function

'Замена с помощью регулярных выражений
'Использован код с сайта: http://vba.valemak.com/vba/regexp/replace/
'Также использованы коды авторов: Андрей VG, Hugo
'Редактор: Jack_Famous
'Тема на форуме: http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=77124&TITLE_SEO=77124-vopros-po-regulyarnym-vyrazheniyam-v-stroke-nayti-zamenit&MID=647893#message647893
'==================================================================================================================================================================================================
Public Function RegExpReplace(str$, ptrn$, Replace$, Glob$, IgnCase$, MulLine$)

If Replace = "перенос" Then Replace = Chr(10)
If Replace = "" Then Replace = ""

RegExpReplace = str
     
Dim RegExp As Object
          
Set RegExp = CreateObject("VBScript.RegExp")
    
    With RegExp
        .Global = Glob
        .IgnoreCase = IgnCase
        .MultiLine = MulLine
        .Pattern = ptrn
    End With
        
On Error Resume Next
RegExpReplace = RegExp.Replace(str, Replace)

Set RegExp = Nothing
     
End Function


Изменено: Jack_Famous - 29.04.2016 12:30:37
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх