Регулярное выражение для рисунка в окружении дополнительных угловых скобок

Я пытаюсь использовать регулярные выражения, чтобы найти число, необязательно окруженное угловыми скобками, т.е. <>, Шаблон, который я использую,

<?(?P<fraction>[-+]?[-+0-9.Ee]+)>?

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

Я хочу сопоставить такие вещи, как:

-11.88
<0.012541>
-<3.14>
<-2.98>

И я не хочу соответствовать

<1.23
<-abcdefg>

Я также не хочу повторять шаблон, который я использую, чтобы соответствовать номеру. Это похоже на подверженное ошибкам решение.

3 ответа

Решение

Вы могли бы использовать именованные условные выражения, если не хотите повторять числовую часть регулярного выражения:

^[-+]?(?P<o><)?[-+0-9.Ee]+(?(o)>|)$

Сломать:

^               # Start
  [-+]?         # Get a -/+ if any
  (?P<o><)?     # Get a < if any
  [-+0-9.Ee]+   # Get the numbers
  (?(o)>|)      # If a < was matched, match a >, otherwise, don't match anything
$               # End

regex101 demo

Ideone демо


Если вы хотите что-то действительно проверить номер (и предотвратить такие вещи, как -<-2>), вы можете использовать что-то вроде этого:

^(?P<s>[-+])?(?P<o><)?(?(s)|[-+]?)\d+(?:\.\d+(?:[Ee][-+]\d+(?:\.\d+)?)?)?(?(o)>|)$

Примечание: я обычно не проверяю такие вещи, как .2e-.3 (то есть десятичные дроби без нуля в начале), поэтому вышесказанное также предотвращает это. Это работает, если строка 0.2e-0.3 хотя, но допускает как начальные, так и конечные нули.

regex101 demo

Наивное решение: скопируйте / вставьте шаблон (первый вариант с угловыми скобками, второй вариант без):

<(?P<fraction>[-+]?[-+0-9.Ee]+)>|(?P<fraction>[-+]?[-+0-9.Ee]+)

Более продвинутое решение: взгляните на условные выражения If-Then-Else в регулярных выражениях. Они позволяют указать шаблон для сопоставления, если определенная группа (именованная или пронумерованная) совпадает. Итак, в вашем случае вы могли видеть, было ли совпадение для левой угловой скобки, и только тогда совпадать с правой угловой скобкой.

Простой и понятный, без специальных функций:

^(-?<\d+\.\d+>)|(<-?\d+\.\d+>)|(-?\d+\.\d+)$

Простота и легкость в обслуживании - это ключ к регулярным выражениям, они лучше всего используются для сопоставления и не выполняют внутри них процедурную условную логику, что вы и пытаетесь сделать

Другие вопросы по тегам