5 / 5 / 0
Регистрация: 07.06.2012
Сообщений: 111
|
||||||
1 | ||||||
Анализ регулярного выражения04.02.2018, 17:43. Показов 1464. Ответов 8
Метки нет (Все метки)
Имеется регулярное выражение для вставки разделителя в числа. Например на входе 12345678 на выходе 12,345,678
\B cоответствует несловообразующей границе. Несловообразующая граница соответствует позиции, в которой предыдущий и следующий символы являются символами одного типа. (Вроде понятно) Движок регулярных выражений идет и по строке и по шаблону. Находит в строке первое соответствие. Если в качестве примера взять строку 12345678, то первое соответствие будет граница между 1 и 2. Что дальше? Дальше движок идет по шаблону, и видит в шаблоне скобочную группу с символами ?= ?= это выражение работает по формуле x(?=y) где соответствие случится, только если после x идет y Теперь движок будет смотреть что стоит после знаков ?= и искать это в строке. Если найдет, то соответствие случится, если не найдет, значит соответствие не случится. У нас после знака стоит выражение (\d{3})+ т.е. нужно найти три цифры, потом еще три, потом еще три и так до конца строки. Получается на этом этапе он находит цифры 234567 Движок продолжает идти по шаблону. Видит в шаблоне (?!\d). Это значит, что после 234567 не должна стоять цифра, а в нашем случае она стоит, значит ничего не происходит, соответствие не найдено. Всё шаблон и строка пройдены до конца. А так как стоит флаг глобального поиска, то весь вышеописанный алгоритм действий повторяется, но только уже не с первого, а со второго символа. И так много раз. И в определенные моменты будут найдены "границы" на которые функция replace поставит запятые. Вот. Вроде что-то, как-то смутно понимается, но сложно. Если кто-то опишет понятнее, буду благодарен.
0
|
04.02.2018, 17:43 | |
Ответы с готовыми решениями:
8
Составление регулярного выражения Переменная внутри регулярного выражения Написание регулярного выражения для pattern Выбрать подстроку с использованием регулярного выражения |
132 / 108 / 22
Регистрация: 23.06.2015
Сообщений: 339
|
|
11.02.2018, 17:47 | 2 |
user7845, Вы ,по-моему впервые на форумах создали тему по логике работы регулярных выражений,причем в сложном аспекте применения регулярных выражений,дело в том,что совпадение может быть не только с фрагментом текста,но также и с позицией в тексте,а при замене,когда не было совпавшего текста,а была найдена только позиция совпадения,замещающий текст(у нас запятая) подставляется в эту позицию.
Процесс сопоставления т шаблону обычно начинается с начала,а в нашем случае в шаблоне задано другое \B( то есть начинаем поиск в позиции между 1 и 2) и с начала шаблона. Имеются два подшаблона-позитивная опережающая проверка (?=шаблон) и негативная опережающая проверка(?!шаблон) У Вас в целом правильная логика рассуждений,поэтому я только подкорректировал Ваш текст: Если в качестве примера взять строку 12345678, то первая позиция будет между 1 и 2. Дальше движок идет по шаблону, и видит в шаблоне позитивную опережающую проверку Далее у нас выражение (\d{3})+ и квантификатор принимает значения 1 и 2 соответственно для каждой испытуваемой позиции. Движок продолжает идти по шаблону. Видит в шаблоне подшаблон негативной опережающей проверки (?!\d). Это значит,что в найденной позиции на три и на шесть символов вправо от исходной испытуваемой позиции далее не должна стоять цифра. А так как стоит флаг глобального поиска, то весь вышеописанный алгоритм действий повторяется, но только уже не с первого, а со второго символа. И так много раз. И в определенные моменты будут найдены две позиции на которые функция replace поставит запятые. Добавлю,что можно (\d{3}) записать в функции как (?:\d{3})в целях повышения эффективности поиска.
1
|
132 / 108 / 22
Регистрация: 23.06.2015
Сообщений: 339
|
|
12.02.2018, 20:38 | 3 |
user7845, К #1 и#2 могу добавить следующее, поскольку описание процесса в #2 очень краткое:
Модификатор(мнимый символ) \b соответствует границе слова, то есть соответствует позиции с одной стороны которой находится символ слова(буква,цифра или знак подчёркивания),а с другой стороны такого символа нет. Мнимый символ \B соответствует позиции внутри слова, то есть с одной и другой стороны от неё находится символ слова(буква,цифра или знак подчёркивания). В регулярках языков Java Script, Perl,PHP задействован алгоритм поиска –НКА(недетерминированный конечный автомат(алгоритм управляется шаблоном), при этом действует принцип возвратов: в случае локальной неудачи поиска совпадения, происходит откат к предыдущему минимальному подшаблону, имеющему переменный квантификатор. Механизм поиска совпадения ( движок) хранит текущие позиции в тексте и шаблоне. Поиск заканчивается удачей, когда текущая позиция в шаблоне выходит за пределы шаблона. В примере текста 12345678 для данной темы не так и много итераций: 1. Процесс сопоставления текста шаблону в нашем случае начинается в тексте с позиции между 1 и 2, ей соответствует подшаблон(мнимый символ ) \B. Далее жадный квантификатор + выбирает максимальное значение 2,чтобы оставаться в цифровом блоке. Соответственно мы смещается вправо на 6 позиций, то есть проверка на наличие цифры справа (опережающая негативная проверка)правее осуществляется в позиции между 7 и 8. Проверка заканчивается локальной неудачей. 2. В соответствии с принципом возвратов происходит откат к предыдущему минимальному подшаблону, то есть к индексу квантификатора 1,то есть мы смещаемся на 3 позиции от исходной между 1 и 2,негативная опережающая проверкана наличие цифры (далее проверка) происходит в позиции между 4 и 5 . Опять локальная неудача, цифра имеется. 3. В соответствии с принципом возвратов происходит откат к предыдущему минимальному подшаблону \B и в тексте мы смещается на одну позицию между 2 и 3 Опять жадный квантификатор + выбирает максимальное значение 2,чтобы оставаться в цифровом блоке( 3 не подойдёт). Опять мы смещается на (3*2=)6 позиций вправо. Проверка на наличие цифры приносит удачу, то есть позиция между 2 и 3 подходит для вставки запятой функцией Replace. 4. И на этом все бы закончилось, но специальный режим поиска с индефикатором g(global) производит откат к предыдущему минимальному подшаблону,имеющему переменный квантификатор , то есть к максимальному индексу жадного квантификатора 1(2 уже не подойдёт, чтобы остаться в цифровом блоке),а позицию в тексте увеличивается на 1 между 3 и 4. Проверка будет осуществляться между 6 и 7 и локальная неудача, опять откат, позицию в тексте увеличивается на 1-мы между 4 и 5 проверка будет между 7 и 8, и локальная неудача вновь, далее откат, А позицию в тексте увеличивается на 1 между 5 и 6,проверка с индексом квантификатора 1 даёт удачу Позиция в тексте между 5 и 6 подошла для вставки запятой функцией Replace. И так нйдены две искомые позиции. Добавлю ,что в конце #2 в предпредпредпоследнем предложении имеется опечатка.Надо так изменить : Весь вышеописанных алгоритм повторяется, но только не с позиции между первым и вторым символом,а с позиции между вторым и тетьим символом.
0
|
5984 / 1993 / 323
Регистрация: 10.12.2013
Сообщений: 6,874
|
|||||||||||
13.02.2018, 08:24 | 4 | ||||||||||
для простоты восприятия можно упростить regex до
/(?=(\d{3})+$)/ и для подопытной строки "12345678" всё отработает идентично --> 12,345,678 но вот если число символов в строке будет кратно 3, появится ненужная нам запятая в нулевой позиции ( ,123,456,789 ). Таким образом, метасимвол \B в начале нужен для исключения таких случаев. оставшаяся часть (?=(\d{3})+$) заставит механизм regexp найти найти такую позицию в строке для вставки запятой, при которой группы из трех цифр кратно уложатся в строку. Тем, кто умеет управляться с Perl, могу посоветовать использовать фантастический модуль Дамиана Конвея ( Damian Conway ) Regexp::Debugger, который наглядно в весёлых картинках покажет, как работает данный regex. 1.pl
0
|
132 / 108 / 22
Регистрация: 23.06.2015
Сообщений: 339
|
|
13.02.2018, 10:37 | 5 |
user7845, в Perl очень иллюстративен вариант с позитивной ретроспективной проверкой
Код
$t=~s!(?<=\d)(?=(?:\d{3})+(?!\d))!,!g; Для Java Script можно приспособить такой вариант: Код
$t=~s!(\d)(?=(?:\d{3})+(?!\d))!$1,!g;
0
|
5 / 5 / 0
Регистрация: 07.06.2012
Сообщений: 111
|
|
13.02.2018, 22:10 [ТС] | 6 |
Спасибо всем за ответы. Есть над чем поразмыслить
0
|
5984 / 1993 / 323
Регистрация: 10.12.2013
Сообщений: 6,874
|
|||||||||||
16.02.2018, 08:55 | 7 | ||||||||||
Не по теме: Может кому будет любопытно:
Добавлено через 37 минут Не по теме: вот так совсем по-человечески:
1
|
958 / 520 / 244
Регистрация: 20.05.2015
Сообщений: 774
|
||||||
17.02.2018, 23:06 | 8 | |||||
user7845, возможно совсем не в тему, но вдруг кому-то пригодится.
В JS есть нативный метод для работы с числами — Intl.NumberFormat .
1
|
5 / 5 / 0
Регистрация: 07.06.2012
Сообщений: 111
|
|
19.02.2018, 10:01 [ТС] | 9 |
Прикольный метод. Не знал о его существовании. Мне пригодится.
0
|
19.02.2018, 10:01 | |
19.02.2018, 10:01 | |
Помогаю со студенческими работами здесь
9
Как написать функцию проверки регулярного выражения? Конец и начало строки для регулярного выражения Каков смысл регулярного выражения в данном коде? Построение регулярного выражения Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |