Регулярное выражение для исключения совпадений на основе шаблона


Я пытаюсь создать регулярное выражение (Perl-совместимое, но не само Perl), которое соответствует следующим критериям:

  • он не должен содержать "R", за которым следует любое количество цифр (без учета регистра), на границе слова
  • могут быть или не быть дополнительные слова и/или пробел, окружающий его
  • является R# содержится в скобках, которые не должны соответствовать

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

^(.(?!b(?:r)d*b))*$
Ниже приведена таблица примеров. Одни работают, другие терпят неудачу.

Для входных строк ниже:

  • n = новая строка
  • s = пространство
  • t = tab

Результаты

+-------------------------------+---------------+--------------+
|         Input string          | Desired Match | Actual Match |
+-------------------------------+---------------+--------------+
| Some text                     | yes           | yes          |
| Some textr1                   | yes           | yes          |
| Some text default(r3)         | yes           | NO           |
| Some text default(abc r3)     | yes           | NO           |
| Some text default(r3 xyz)     | yes           | NO           |
| Some text default(abc r3 xyz) | yes           | NO           |
| Some text r12 default(r3)     | no            | no           |
| Some text r1                  | no            | no           |
| Some r1 text                  | no            | no           |
| sR12 Some text               | no            | no           |
| Some text r1 somethingElse    | no            | no           |
| R1                            | no            | YES          |
| ssR2                        | no            | no           |
| R3ss                        | no            | YES          |
| tr4                          | no            | no           |
| tsR5t                      | no            | no           |
+-------------------------------+---------------+--------------+

Может ли кто-нибудь предоставить рабочее регулярное выражение?

Майк В.

1 2

1 ответ:

Вы можете использовать этот шаблон:

(?i)^(?>[^r(]++|(?<!\\[ts])\Br|r(?![0-9])|(\((?>[^()]++|(?1))*\))|\()++$

Детали узора:

(?i)                  # modifier: case insensitive
^                     # anchor: begining of the string
(?>                   # open an atomic group
    [^r(]++           # all characters except r and opening parenthesis
  |                   # OR
    (?<!\\[ts])\Br    # r without word boundary and not preceded by \t or \s
  |                   # OR
    r(?![0-9])        # r (with word boundary or preceded by \t or \s) not followed by a digit
  |                   # OR
    (                 # (nested or not parenthesis): open the capture group n°1
        \(            # literal: (
        (?>           # open an atomic group
            [^()]++   # all characters except parenthesis
          |           # OR
            (?1)      # (recursion): repeat the subpattern of the capture group n°1
        )*            # repeat the atomic group (the last) zero or more times
        \)            # literal: )
    )                 # close the first capturing group
  |                   # OR
    \(                # for possible isolated opening parenthesis
)++                   # repeat the first atomic group one or more times
$                     # anchor: end of the string
Примечание: если в вашем посте \t и \s не являются литералами, вы можете удалить (?<!\\[ts]).