Можем ли мы использовать условные выражения, основанные на взглядах? - PullRequest
0 голосов
/ 21 декабря 2018

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

  \b       # "word" boundary
  (?<=\$)  # Assert that current position is preceded by $
  \d+\b    # digits, boundary
  (?!\$)   # Assert that current position is not followed by $
|          # alternation
  \b       # boundary
  (?<!\$)  # Assert that current position not preceded by $
  \d+\b    # digits, boundary
  (?=\$)   # Assert that current position is followed by $

Есть ли способ в PCRE использовать условиеделать подобное с условностями.( demo )

(                 # capture 1, because we can't quantify lookarounds
  (?<=\$)         # Asserts that $ precedes current position
)?                # close capture 1, make it "optional" (0 or 1 times)

\b                # boundary
\d+               # digits
\b                # boundary
(?(1)             # conditional that capture #1 was a success
  (?!\$)          # if successful, assert that it is not followed by a #
|
  (?=\$)          # unsuccessful, assert that this position is followed by a $
)

Примечание: Границы слова важны, так что оба фиксируют целое число, в противном случае регулярное выражение переместится на один шаг назадшаг, вырезая цифру из многозначного числа.

Оба выражения выше соответствуют $ 15 и 16 $, но не $ 17 $, как они должны.Без границ они соответствовали бы 15, 16 и 1 долл. Из 17 долл.

1017 *

1 Ответ

0 голосов
/ 21 декабря 2018

Рабочий раствор ( демо ).Решение проблемы - 99 шагов, что является ненужной жертвой в этом простом примере.Есть ситуации, когда жертва, если таковая имеется, более чем разумна.

Это оказалось очень простым.Сделайте группу захвата 1 притяжательной .Это означает, что что бы он ни захватывал, он не сдастся, если регулярное выражение попытается вернуться назад.Здесь это означает, что, как только он решит, что число должно предшествовать $, он не позволит возврату регулярного выражения, если после номера также следует $.Он сдастся и пойдет дальше, найдя следующую границу, за которой следуют цифры, и осмотрит окрестности.

(                 # capture 1, because we can't quantify lookarounds
  (?<=\$)         # Asserts that $ precedes current position
)?+               # close capture 1, make it "optional" (0 or 1 times)
                  # the possessive quantifier is the only change to the regex
                    # + is only 'possessive' when it's the second character of a quantifier

\b                # boundary
\d+               # digits
\b                # boundary
(?(1)             # conditional that capture #1 was a success
  (?!\$)          # if successful, assert that it is not followed by a #
|
  (?=\$)          # unsuccessful, assert that this position is followed by a $
)
...