Страницы: 1
RSS
Регулярные выражения. RegExp. Заменить символы между двумя цифрами
 
Доброго времени суток, Планетяне!
Не думал, что так тупану  :D выручайте

Есть строка, в которой нужно заменить видимые знаки "умножения" (типа буквы "ха" в кириллице и "экс" в латинице) на звёздочку.

То есть шаблон должен быть что-то вроде "(\d)( *)(?=X|x|Х|х)( *)(\d)":
• между 2мя цифрами стоит "ха" или "икс"
• буквы могут быть в обоих регистрах
• могут быть отбиты одним и более пробелами с каждой из сторон или пробелы могцт отсутствовать (совсем или с одной стороны)
Что накалякал
Тестер
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал: То есть шаблон должен быть что-то вроде "(\d)( *)(?=X|x|Х|х)( *)(\d)":
Для Вашего примера подойдет такой шаблон
Код
"\d+.[XxХх].\d+"
или
"\d+\s*[XxХх]\s*\d+"
Изменено: Sanja - 05.08.2019 16:05:45
Согласие есть продукт при полном непротивлении сторон
 
Sanja, смысл понял - благодарю! Оттестирую и отпишусь.
А в каких случаях нужен "?="?. Я читал и подумал, что как раз моё - а оно всё гораздо проще оказалось.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Я  читал  и подумал
Привет, Алексей.
Точно думали?
Цитата
Дальнейший подбор начинается немедленно, а не после символов, входящих в скобки. НЕ фиксирует подбор в коллекции SubMatces.
Это просто проверка на то, что наш шаблон удовлетворяет условию, что после предшествующих определений в шаблоне идёт именно (?=что-то там). Зажирнённое никогда не входит в результат Match.Value. Использование вне проверки, что заканчивается, по существу бессмысленно. По другому проверка с возвратом что-заканчивается на.. без включения в результат отбора.
Изменено: Андрей VG - 05.08.2019 17:03:44
 
Андрей VG, приветствую!  :)
Спасибо - редко работаю с ними и поэтому, наверное туго.
А как лучше и быстрее (для скорости работы) сделать? Можно ли обойтись без проверки .Test и .Execute, что бы сразу заменить "иксы" на звёздочки одним Replace'ом?
Изменено: Jack Famous - 05.08.2019 17:07:39
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Можно стандартным образом:

=RegExpReplace(A1;"(\d\s*)[xх](\s*\d)";"$1*$2";;ИСТИНА)
Код
Public Function RegExpReplace(ByVal Text As String, ByVal Pattern As String, ByVal Replace As String, _
    Optional ByVal Glob As Boolean = False, _
    Optional ByVal IgnoreCase As Boolean = False, _
    Optional ByVal MultiLine As Boolean = False)
    Static regex As Object
    If regex Is Nothing Then
      Set regex = CreateObject("VBScript.RegExp")
    End If
    regex.Pattern = Pattern
    regex.Global = Glob
    regex.MultiLine = MultiLine
    regex.IgnoreCase = IgnoreCase
    RegExpReplace = regex.Replace(Text, Replace)
End Function
Изменено: sokol92 - 05.08.2019 17:40:32
Владимир
 
Владимир, приветствую! Вы тоже, как всегда, выручаете!  :idea:
Не успел вчера почитать толком про SubMatches, а, в частности, про применение "$" в шаблоне — как оказывается, варианту от Sanja просто не хватило скобок для того, чтобы после обратиться к найденному через "$".

Подошёл вот такой шаблон: "(\d) *[XxХх] *(\d)". IgnorCase убрал, т.к. (вроде) лучше перечислить ещё 2 значка, чем проверять всё, но больше из-за того, что далее в коде могут быть другие шаблоны, а переключать IgnoreCase в цикле я не хочу. \s заменил на пробел символом, т.к. \s - пробельный символ. Эквивалентно [\f\n\r\t\v] и тесты по TrimRE показали, что так хоть и чуточку, но быстрее  :)

Всем огромное спасибо!
Изменено: Jack Famous - 06.08.2019 10:01:00
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Приветствую!
Нагородил в тот раз, так толком и не разобравшись. Прошу помощи ещё раз  :)
Код
Изменено: Jack Famous - 08.07.2021 16:20:58
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, у Вас большие иксы вперемешку с большой ха в исходнике:
x1x2X3х4ХХ5x
Попробуйте такой паттерн для искомого:
X{1,}
или такой:
[X,Х]{1,}


Фигню написал. Просто сделайте замену паттерна:
[X,Х]
на звёздочку.
Изменено: JayBhagavan - 08.07.2021 16:12:32

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, вообще ничего не понял - у вас получилось?
Заменять не вариант, потому что условие "если между 2мя цифрами стоит ха или икс вне зависимости от регистра, то заменить её на жирную центральную точку =СИМВОЛ(149)"
Изменено: Jack Famous - 08.07.2021 16:19:23
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Не то. Теперь понял. Надо подумать...
Подумал
Изменено: JayBhagavan - 08.07.2021 17:17:29

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
JayBhagavan, спасибо, но это слишком костыльно и долго - быстрее тогда уж будет строковыми  :)
А вообще мне просто нужно правильно шаблон написать - то есть именно шаблон мне нужен, а не сам результат, т.к. добиться такого результат можно и без регулярок и с шаблоном "$1•$3", но в несколько проходов (Do…Loop) - будет и короче и быстрее
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Доброе время суток.
Вариант для одной x
Код
Private PRegExp As Object

Function ReplaceMultSign(ByVal inText As String) As String
    Dim foo
    If PRegExp Is Nothing Then
        Set PRegExp = CreateObject("VBScript.RegExp")
        PRegExp.IgnoreCase = True
        PRegExp.Global = True
        PRegExp.Pattern = "(\d)( *(?:x|х)+ *)(?=\d)"
    End If
    Set foo = PRegExp.Execute(inText)
    ReplaceMultSign = PRegExp.Replace(inText, "$1 " & ChrW(&H2022) & " ")
End Function
как выкрутить для более одной. Увы, похоже RegExp.Replace нет указания на число повторов, тогда только через SubMatches и пересбор строки, скорее всего.
 
Андрей VG, как всегда великолепно - огромное спасибо!  :idea:
Принцип работы (разбор шаблона, как я понял):
КОД
Интересный момент - несмотря, на то, что вместо 2ух символов можно написать 4, но при этом не игнорировать регистр, с игнорированием чуть быстрее
Цитата
Андрей VG: Вариант для одной x
Бонус: по факту код заменяет ВСЕ разделители "ха" и "икс" между двумя цифрами на один заданный
Браво!  8)  8-0

P.S.: основная справка по RegExp (всё там же)
Изменено: Jack Famous - 09.07.2021 13:36:35
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх