Могу ли я написать условное обозначение PCRE, для которого требуется только часть без совпадения? - PullRequest
1 голос
/ 11 октября 2019

Я пытаюсь создать регулярное выражение, чтобы определить, содержит ли строка число для оператора SQL. Если значение числовое, то я хочу добавить 1 к нему. Если число не числовое, я хочу вернуть 1. Более или менее. Вот SQL:

SELECT 
   field,
   CASE
     WHEN regexp_like(field, '^ *\d*\.?\d* *$') THEN dec(field) + 1
     ELSE 1
   END nextnumber
FROM mytable

Это на самом деле работает и возвращает что-то вроде этого:

INVALID     1
00000       1
00001E      1
00379       380
00013       14
99904       99905

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

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

Вот измененныйregex: ^ ([+-]?)*\d*\.?\d*(?(1) *|[+-]? *)$

Это работает на regex101.com , но для того, чтобы это работало, мне нужно что-то перед конвейером, поэтому я должен продублировать следующеешаблон в yes-pattern и no-pattern.

Все, что связано с этим вопросом: как можно избежать такого дублирования?


РЕДАКТИРОВАТЬ: DB2 for i использует International Components for Unicode для обеспечения обработки регулярных выражений,Оказывается, эта библиотека не поддерживает условные выражения, такие как PRCE, поэтому я изменил теги для этого вопроса. Ответ, данный Виктором Стрибьевым, предоставляет рабочую альтернативу условному, используя негативный взгляд.

1 Ответ

1 голос
/ 11 октября 2019

Вам не нужно дублировать конечный шаблон, просто переместите его за пределы условного:

^ *([+-])?\d*\.?\d*(?(1)|[+-]?) *$

См. Демоверсию regex . Итак, часть «да» пуста, а часть «нет» имеет необязательный шаблон.

Вы также можете решить эту проблему с помощью простого отрицательного взгляда:

^ *([+-](?!.*[-+]))?\d*\.?\d*[+-]? *$

См. другойregex demo . Здесь ([+-](?!.*[-+]))? совпадает (необязательно) с + или -, за которыми не следует ни один символ 0+, за которым следует другой + или -.

...