preg_match_all соответствует необязательным скобкам

Попытка preg_match_all

#THING or [#THING]

Это работает для первого

/(#[A-Z]+)/ 

Для другого со скобками я думал, что что-то подобное должно работать, но это не так.

/(\[?#[A-Z]+\]?)/  

В конечном счете, я хочу соответствовать любому из этих

#THING [(#THING)] or [anything(#THING)anything]

person Delorimier    schedule 22.06.2017    source источник
comment
Не могли бы вы объяснить требования?   -  person Wiktor Stribiżew    schedule 22.06.2017
comment
Ваше второе регулярное выражение соответствует [#THING], как показано здесь   -  person roberto06    schedule 22.06.2017
comment
anythings и () также должны быть захвачены?   -  person chris85    schedule 22.06.2017
comment
Необходимо сделать preg_replace_all для соответствия и замены любого из них - #ANYUPPERCASE [(#ANYUPPERCASE)] [anything(#ANYUPPERCASE)anything] Все символы должны быть захвачены в любом из них.   -  person Delorimier    schedule 22.06.2017
comment
Да, мое исходное регулярное выражение работало для [#THING] — моя ошибка   -  person Delorimier    schedule 22.06.2017
comment
Если это не пара неэкранированных [, закрывающая квадратная скобка ] не имеет особого значения. Нет необходимости избегать этого.   -  person axiac    schedule 22.06.2017
comment
То же самое для } и )?   -  person Delorimier    schedule 26.06.2017


Ответы (2)


Это кажется надежным/надежным шаблоном:

~#[A-Z]+|\[[^#\]]*\(#[A-Z]+\)[^\]]*]~

Демонстрация шаблона

~         #pattern delimiter
#[A-Z]+   #match hash symbol followed by one or more uppercase letters
|         #or
\[        #match an opening square bracket
[^#\]]*   #match zero or more non-hash/non-closing square bracket characters
\(        #match opening parenthesis
#[A-Z]+   #match hash symbol followed by one or more uppercase letters
\)        #match closing parenthesis
[^\]]*    #match zero or more non-closing square bracket characters
]         #match a closing square bracket
~         #pattern delimiter

Этот шаблон ищет подстроку «хэштега» без символов [()] ИЛИ подстроку «хэштега», которая будет плотно заключена в (), а затем слабо заключена в [], которая также может содержать некоторые символы до ( или после ).

Этот шаблон эффективен, потому что он использует жадные квантификаторы и не использует группы захвата.

person mickmackusa    schedule 24.02.2018
comment
@Delorimier Ваша задача связана с проверкой или извлечением? Если ваша входная строка содержит скобки, вы действительно хотите извлечь подстроку от [ до ] или вам нужны только заглавные буквы после th #? Я хотел бы лучше понять вашу задачу, чтобы я мог предоставить вам наилучший шаблон. - person mickmackusa; 24.02.2018
comment
Вау, спасибо - это очень похоже на то, что я наконец придумал. Мне нужно изолировать шаблоны от строки, которая может содержать много. С тех пор мои потребности стали немного сложнее, так как шаблоны могут быть встроены в другой, например: игнорировать эту часть [до(#ЭТО) после[до(#ДРУГОЕ]после]] игнорировать эту часть #ЗАПИСАТЬЭТО - person Delorimier; 25.02.2018

РЕДАКТИРОВАТЬ: Кажется, это работает для меня.

  ((\[(.*))?\(?#[A-Z]+\)?((.*)\])?)

Правильное соответствие этим:

#ANYUPPERCASE
[(#ANYUPPERCASE)]
[anything(#ANYUPPERCASE)anything]
person Delorimier    schedule 22.06.2017
comment
ой, не соответствует #ЛЮБОЙ ПРОПИСНОЙ РЕГИСТР - person Delorimier; 22.06.2017
comment
Код исправлен в приведенном выше примере - person Delorimier; 22.06.2017
comment
Этот ответ будет фактически соответствовать несбалансированным подстрокам в квадратных скобках: regex101.com/r/kAyDHg/2 - person mickmackusa; 24.02.2018