В попытке использовать Bash встроенного в регулярных выражениях для разбора следующих типов строк, которые должны быть преобразованы в выражение подстановки Perl (кавычки не являются частью данных)шаблон обратной ссылки на дополнительный захвата подвыражение
'~#A#B#'
#^^^-- Replacement string.
#| +---- Pattern string.
#+------ Regular expression indicator (no need to escape strings A and B),
# which is only allowed if strings A and B are surrounded with ##.
# Strings A and B may not contain #, but are allowed to have ~.
'#A#B#'
#^------ When regex indicator is missing, strings A and B will be escaped.
'A#B'
# Simplified form of '#A#B#', i. e. without the enclosing ##.
# Still none of the strings A and B is allowed to contain # at any position,
# but can have ~, so leading ~ should be treated as part of string A.
Я попытался следующий шаблон (опять же, без кавычек):
'^((~)?(#))?([^#]+)#([^#]+)\3$'
то есть, он объявляет ведущий ~#
дополнительный (и ~
в нем еще дополнительно), затем захватывает части A
и B
, и требует, чтобы конечный #
присутствовал только в том случае, если он присутствовал в лидере. Ведущий #
захватывается только для соответствия только обратной ссылки - он не нужен нигде, тогда как ~
будет захвачен для проверки по сценарию впоследствии.
Однако эта схема работает только как ожидается, с наиболее полными типами входных данных:.
'~#A#B#'
'#A#B#'
но не для
'A#B'
I. е, когда ведущая часть отсутствует, \3
не соответствует. Но если \3
заменяется на .*
, совпадение будет успешным, и можно видеть, что ${BASH_REMATCH[3]}
- пустая строка. Это то, что я не понимаю, при условии, что неустановленные переменные рассматриваются как пустые строки в Bash. Как мне сопоставить обратную ссылку с дополнительным контентом?
В качестве обходного пути, я мог бы написать альтернативный порядок
'^(~?)#([^#]+)#([^#]+)#$|^([^#]+)#([^#]+)$'
, но это приводит к различным группам захвата для каждого возможного случая, что делает код менее интуитивно.
Важное примечание. Как упоминал в своем комментарии @anubhava, сопоставление backreference может быть недоступен в некоторых строках Bash (возможно, это вопрос вариантов сборки, а не номера версии или даже какой-либо внешней библиотеки). Этот вопрос, конечно, ориентирован на те среды Bash, которые поддерживают такую функциональность.
Попробуйте ''^(~? #?) ([^ #] +) # ([^ #] +) \ 1 $ '', или, возможно, если' ~ 'не нужно проверять на наличие как в начале и в конце строки попробуйте '^ ~? (#?) ([^ #] +) # ([^ #] +) \ 1 $' –
Простите за то, что вы не так понятны, но ведущий ' 'может присутствовать только в том случае, если' # 'есть - они не являются двумя независимыми частями. –
Попробуйте ['^ (~? (#?)) ([^ #] +) # ([^ #] +) \ 2 $'] (https://regex101.com/r/sF1qY1/1) –