Соответствие регулярному выражению, исключающее символы в скобках - PullRequest
3 голосов
/ 11 марта 2012

У меня есть следующие типы строк.

BILL SMITH (USA)
WINTHROP (FR)
LORD AT WAR (GB)
KIM SMITH

С этими строками у меня есть следующие ограничения: 1. все заглавные буквы 2. может быть от 2 до 18 чартеров 3. не должно быть пробелов или возврата каретки в конце 4. аббревиатуру страны в скобках следует исключать 5. у некоторых имен не должно быть страны в скобках, и они тоже должны совпадать

После применения моего регулярного выражения я хотел бы получить следующее:

BILL SMITH (USA)  => BILL SMITH
WINTHROP (FR) => WINTHROP
LORD AT WAR (GB) = LORD AT WAR
KIM SMITH => KIM SMITH

Я придумал следующее регулярное выражение, но я не нашел совпадений:

* * 1010

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

UPDATE:

Однако я получил несколько хороших ответов, но до сих пор ни одно из решений для регулярных выражений не удовлетворяло всем ограничениям. Хитрая часть, кажется, состоит в том, что некоторые строки имеют страну в скобках, а некоторые нет. В одном случае строки без страны не сопоставлялись, а в другом она возвращала правильную строку вместе с сокращением страны без скобок. (См. Комментарии ко второму ответу.) Одно уточнение: все строки, с которыми я буду сопоставлять, будут отправной точкой строки. Не уверен, помогает ли это или нет. Еще раз спасибо за вашу помощь.

Ответы [ 3 ]

2 голосов
/ 11 марта 2012

Вот одно из решений:

^((?:[A-Z]|\s){2,18}+?)(?:\s\([A-Z]+\))?$

См. Рубуляр . Обратите внимание, что в скобках указано 18 символов - не уверен, как вы хотите, чтобы он вел себя специфически. Если вы хотите убедиться, что вся строка не длиннее 18 символов, я советую просто набрать unless line.length < 18 ... Аналогично, если вы хотите убедиться, что в конце нет пробелов, я рекомендую использовать line.strip. Это значительно снизит сложность необходимого вам регулярного выражения и сделает ваш код более читабельным.

Редактировать: также работает, когда после имени не используются скобки.

1 голос
/ 11 марта 2012

Вы также можете просто использовать gsub, чтобы удалить части, которые вы не хотите.Чтобы удалить все в скобках, вы можете сделать:

str.gsub(/\s*\([^)]*\)/, '')
1 голос
/ 11 марта 2012

Самая большая ошибка в том, что вы написали (^?!...), где вы имели в виду (?=...). Первый означает «необязательный якорь начала строки, за которым следует !, за которым следует ..., внутри группы захвата»; последнее означает «позицию в строке, за которой следует ...». Исправив это, а также сделав несколько других настроек, и добавив требование, чтобы начальная строка заканчивалась буквой, мы получаем:

[A-Z\s]{1,17}[A-Z])(?=\s*\([A-Z]{1,3}\)

Обновление на основе комментариев OP: Поскольку это всегда будет совпадать в начале строки, вы можете использовать \A, чтобы "привязать" ваш шаблон к началу строки. После этого вы можете избавиться от утверждения о предвкушении. Это:

\A[A-Z][A-Z\s]{0,16}[A-Z]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...