Любой способ использовать регулярное выражение с двумя различными парами разделителей?

Я добавил смайлики в свое приложение для Android и использую Regex в Java, поэтому назначенные им коды будут соответствовать регулярному выражению (которое содержит пару разделителей для использования), в результате чего символы будут отображаться как изображений.

Некоторые коды смайликов, например, sad, happy, smile,

До сих пор это было так:

  • Разделители: ( а также )

  • Регулярное выражение: \\(([.[^\\(\\)]]+)\\)

  • Пример соответствия кодов смайликов: (sad), (happy), (smile),

Я заметил, что для некоторых новых смайликов, которые я добавил, пользователю будет удобнее набирать свои коды, используя другую пару разделителей, например букву z а также ,, Тогда второй случай будет выглядеть так:

  • Разделители: z а также ,

  • Регулярное выражение: z([.[^z\\,]]+)\\,

  • Пример соответствия кодов смайликов: zsad,, zhappy,, zsmile,,

В таком случае я хочу объединить оба эти двух регулярных выражения, чтобы пользователь мог вводить код смайликов, используя любую из двух пар разделителей, в зависимости от того, что он или она предпочитает, и они будут сопоставлены. Например, грустные эмодзи будут сопоставлены, и они будут отображаться в виде изображения каждый раз, когда они написаны как (sad) или жеzsad,, как в:

Привет. (грустно) У меня плохие новости. zsad,

Эй... (грустно)

Хорошо. До свидания. zsad,

Я пытался использовать оператор чередования и обходные пути безуспешно. В следующих двух регулярных выражениях у меня были совпадения только с тем, что осталось от | генератор переменного тока (и я хочу совпадения для левой и правой сторон, конечно):

\\(([.[^\\(\\)]]+)\\)|z([.[^z\\,]]+)\\,

z([.[^z\\,]]+)\\,|\\(([.[^\\(\\)]]+)\\)

И в следующих регулярных выражениях у меня не было совпадений вообще:

(\\(([.[^\\(\\)]]+)\\)|z([.[^z\\,]]+)\\,), (\\(([.[^\\(\\)]]+)\\))|(z([.[^z\\,]]+)\\,)

(z([.[^z\\,]]+)\\,|\\(([.[^\\(\\)]]+)\\)), (z([.[^z\\,]]+)\\,)|(\\(([.[^\\(\\)]]+)\\))

\\(|z([.[^\\(\\z\\,)]]+)\\)|\\,, (\\(|z)([.[^\\(\\z\\,)]]+)(\\)|\\,)(\\()|(z)([.[^\\(\\z\\,)]]+)(\\))|(\\,)

(?=\\(([.[^\\(\\)]]+)\\))(?=z([.[^z\\,]]+)\\,), (?=.*\\(([.[^\\(\\)]]+)\\))(?=.*z([.[^z\\,]]+)\\,)

Извините за гигантский текст, я только хотел дать как можно больше подробностей. Кто-нибудь знает, что я делаю или пишу неправильно, и какое регулярное выражение я могу использовать, чтобы оно соответствовало обоим zemojicode, а также (emojicode)? Ваша помощь будет очень ценится.

3 ответа

Я бы наверное пошел с

\((\w+)\)|z(\w+),

что я считаю проще, и, как ваши собственные попытки, просто захватить фактический токен. \w также допускает цифры и подчеркивание в токене, что я не знаю, если вы считаете плюсом, но вряд ли должно быть недостатком (?).

Так как строка Java:

 \\((\\w+)\\)|z(\\w+),

Проверьте это здесь, в regex101.

В качестве альтернативы я бы хотел упомянуть об этом:

[(z](\w+)[),]

Это даже проще, но не имеет встроенной проверки синтаксиса. Другими словами, это позволило бы комбинацию разделителей, например (sad, а также zhappy), что можно считать недостатком.

С уважением

Java не позволяет использовать повторяющиеся имена для групп захвата, а также не имеет поддержки сброса ветви и условных выражений. Вам нужно использовать чередование, а затем действовать в зависимости от того, как вам нужно обрабатывать совпадения.

Итак, используйте это регулярное выражение:

\(([.[^()]]+)\)|z([.[^z,]]+),

Не забудьте удвоить обратную косую черту в коде Java.

Проверьте это демо, которое обрабатывает только значения совпадений:

String s = "Hi. (sad) I've got bad news. zsad,\nHey... (sad)\nOkay. Bye. zsad,";
System.out.println(s.replaceAll("\\(([.[^()]]+)\\)|z([.[^z,]]+),", "<<$0>>")); 

Выход:

Hi. <<(sad)>> I've got bad news. <<zsad,>>
Hey... <<(sad)>>
Okay. Bye. <<zsad,>>

Вы можете использовать что-то вроде этого:

(z[a-zA-Z]*,|\([a-zA-Z]*\))

Вот пример

Будет захватывать z<anylettershere>, или же (<anylettershere>)

Чтобы соответствовать более 1 в сообщении, используйте global, который, вероятно, понадобится, и он включен в пример ссылки. Он соответствует предложенным вами предложениям по трем отдельным тестерам Java regex, которые я нашел.

редактировать

Просто примечание, любой из \ символы, возможно, должны быть удвоены. Я в первую очередь использую PHP, а не Java, поэтому я не настолько осведомлен об этом, но приведенный пример станет:

(z[a-zA-Z]*,|\\([a-zA-Z]*\\))
Другие вопросы по тегам