Разбор переменных внутри строки с использованием регулярного выражения
У меня есть небольшая проблема с регулярными выражениями с ColdFusion.
У меня есть строка:
Hi my name is {firstname}. and i live in {towncity} my email address is {email}
Я хотел бы знать, как мне найти все строки в моей строке, которые заключены в набор {}
скобки? Я хотел бы разбить все соответствующие строки в массив, чтобы я мог использовать результаты данных запроса.
Также это часто используемый шаблон для обработки строк в совпадающих строках для объединения переменных данных?
Любая помощь с благодарностью.
3 ответа
Простой ответ
Чтобы найти все строки в скобках, вы можете использовать rematch и простое выражение \{[^{}]+\}
объяснение
Обратные слеши \
перед каждой скобкой, чтобы избежать их, и пусть они действуют как буквальные скобки (в противном случае они имеют особое значение).
[^
...]
является отрицательным символьным классом, говорящим соответствует любому отдельному символу, который НЕ является одним из тех, которые содержатся внутри, и жадным +
квантификатор говорит ему, чтобы он соответствовал как можно большему количеству, но по крайней мере одному, из предыдущего пункта.
Таким образом, используя [^{}]+
между фигурными скобками означает, что он не будет соответствовать вложенным или непревзойденным фигурным скобкам. (При использовании \{.*?\}
может соответствовать двум открывающим скобкам. Обратите внимание *?
это ленивый квантификатор, он ничего не соответствует (если возможно), но столько, сколько требуется.)
Расширенный ответ
Однако, поскольку вы говорите, что результаты получены из запроса, способ сопоставления только тех значений, с которыми вы имеете дело, - это использовать ColumnList запроса для формирования выражения:
`\{(#ListChangeDelims(QueryName.ColumnList,'|')#)\}`
Это превращает ColumnList в список с разделителями по конвейеру - набор альтернатив, сгруппированных в круглых скобках - т.е. сгенерированный шаблон будет выглядеть так:
\{(first_name|towncity|email)\}
(содержимое этой группы входит в группу захвата 1).
Чтобы фактически заполнить текст (а не просто сопоставить), вы можете сделать что-то подобное, за исключением того, что здесь нет необходимости в регулярном выражении, просто прямая замена во время циклического прохождения по столбцам:
<cfloop index="CurColumn" list=#QueryName.ColumnList#>
<cfset text = replace( text , '{#CurColumn#}' , QueryName[CurColumn][CurrentRow] , 'all' ) />
</cfloop>
(Так как это стандартная замена, нет необходимости избегать скобок с обратными слешами; здесь они не имеют особого значения.)
Использовать reMatch(reg_expression, string_to_search)
функция.
Подробности о регулярных выражениях в Coldfusion 10 находятся здесь. (Я считаю, что регулярное выражение в CF8 будет примерно таким же.)
Используйте следующий код.
<cfset str = "Hi my name is {firstname}. And I live in {towncity} my email address is {email}.">
<cfoutput>Search string: <b>#str#</b><br />Search result:<br /></cfoutput>
<cfset ret = reMatch("\{[\w\s\(\)\+\.@-]+\}", str)>
<cfdump var ="#ret#">
Это возвращает массив со следующими записями.
- {имя}
- {} Towncity
- {Эл. адрес}
[]
Скобки в регулярных выражениях CF определяют набор символов, соответствующий одному символу. Вы положили +
после скобок, чтобы соответствовать один или несколько символов из набора символов, определенных внутри []
, Например, чтобы соответствовать одной или нескольким заглавным буквам, вы можете написать [A-Z]+
,
Как подробно описано в ссылке выше, CF определяет ярлыки для соответствия различным символам. Те, что я использовал в коде: \w
соответствовать буквенно-цифровому символу или подчеркиванию, \s
чтобы соответствовать символу пробела (включая пробел, табуляцию, перевод строки и т. д.).
Соответствовать следующим специальным символам +*?.[^$({|\
вы избежите их, написав обратную косую черту \
до них.
Исключением является тире -
символ, который не может быть экранирован обратной косой чертой. Итак, чтобы использовать его как литерал, просто поместите его в самый конец набора символов, как я делал выше.
Используя приведенное выше регулярное выражение, вы можете извлечь символы, например, из следующей строки.
<cfset str = "Hi my name is { John Galt}. And I live in {St. Peters-burg } my email address is {john@exam_ple.com}.">
Результатом будет массив со следующими записями.
- {Джон Галт}
- {St. Петерс-Бург}
- {} John@exam_ple.com
Там могут быть гораздо лучшие способы сделать это, но используя что-то вроде rematch( '{.*?}', yourstring )
даст вам массив всех совпадений.
Для дальнейшего использования я сделал это с помощью замечательного RegExr, действительно хорошей онлайн-программы проверки регулярных выражений. Полное раскрытие, это не специально для ColdFusion, но это отличный способ проверить вещи.