2011-12-29 5 views
1

Просто примечание: я немного новичок в регулярном выражении. Возможно, хороший ответ на этот вопрос будет связан с тем, чтобы связать меня с ресурсом, который объясняет, как работают эти условия.Условия сопоставления в Regex

Допустим, у меня есть название улицы, например, 23-я Санкт-Петербургская или 5-я улица. Я бы хотел получить избавиться от продолжающихся «th», «rd», «nd» и «st». Как это может быть сделано?

Прямо сейчас у меня есть выражение: (st | nd | rd | th). Проблема в том, что он также будет соответствовать названиям улиц, которые содержат «st», «nd», «rd» или «th». Так что мне действительно нужно условное совпадение, которое ищет как минимум один номер перед собой (т.е. 1-й, а не уличный).

Спасибо!

+1

Подсказка: найдите эти слова после цифр. –

+0

Пробовал это, но он заканчивается тем, что соответствует всей строке, а не только сокращению, из которого я хочу избавиться. –

+0

hint2: Добавить пробел после (st | nd | rd | th): P – Nobita

ответ

5

Это звучит, как вы просто хотите, чтобы соответствовать порядковый суффикс (ст | й | й | е место), да?

Если ваш двигатель regex поддерживает его, вы можете использовать lookbehind assertion.

/(?<=\d)(st|nd|rd|th)/ 

Это соответствует (st|nd|rd|th) только если перед цифрой \d, но матч не отражает саму цифру.

+0

Проблема: он будет соответствовать 'azoiu32rdzeriuoiu' – fge

+0

@fge True. Для предотвращения этого вы полагаете, что можно с уверенностью предположить, что ему предшествует пробел, а затем только цифры (например, '(? <= \ D +)')? Я ненавижу когда-либо делать предположения ... – Wiseguy

+0

@fge Это не проблема. Он сказал, что хочет соответствовать только «st | nd | rd | th», если перед ним есть цифры. Именно это предполагает, что lookbehind поддерживаются в используемом им двигателе регулярных выражений. Есть ли действительно улица, которая имеет номера в имени с буквами до и после? – Paulpro

1

Попробуйте использовать это регулярное выражение:

(\d+)(?:st|nd|rd|th) 

Я не знаю, рубин. В PHP я хотел бы использовать что-то вроде:

preg_replace('/(\d+)(?:st|nd|rd|th) /', '$1', 'South 2nd Street'); 

удалить суффикс,

+0

Подходите ближе! Однако, используя метод gsub от Ruby, «South 2nd Street» становится «South Street». –

+0

снова проверьте мой ответ – piotrekkr

2

Что вы действительно хотите - это якоря.

Try и заменить глобально:

\b(\d+)(?:st|nd|rd|th)\b 

с первой группой.

Объяснение:

  • \b -> соответствует позиции где либо слово символ (цифра, буква, символ подчеркивания) сопровождается, не символ слова (ни один из предыдущей группы), или задний ход;
  • (\d+) -> соответствует одной или нескольким цифрам и фиксирует их в первой группе (1 долл. США);
  • (?:st|nd|rd|th) -> соответствует любому из st, и т.д ... wihtout захватив его ((?:...) не является отлов группа);
  • \b -> см. Выше.

Демонстрация с помощью Perl:

$ perl -pe 's/\b(\d+)(?:st|nd|rd|th)\b/$1/g' <<EOF 
> Mark, 23rd street, New Hampshire 
> I live on the 7th avenue 
> No match here... 
> azoiu32rdzeriuoiu 
> EOF 
Mark, 23 street, New Hampshire 
I live on the 7 avenue 
No match here... 
azoiu32rdzeriuoiu 
+0

Это не сработает в начале строки и не будет работать примерно на половине языков, которые не реализуют lookbehind. Вместо того, чтобы искать пространство, почему бы не использовать другой пограничный якорь '\ b'? – Amadan

+0

Я собирался отредактировать решение, чтобы включить \ b вместо этого, но отвлекся: p Редактирование ... – fge

+0

Это удаление всего названия улицы (т.е. 4-го). –

0

Чтобы удалить порядковый номер:

/(\d+)(?:st|nd|rd|th)\b/$1/ 

Вы должны захватить номер, так что вы можете заменить матч с ним.Вы можете захватить ординал или нет, это не имеет значения, если вы не хотите выводить его где-то еще.

http://www.regular-expressions.info/javascriptexample.html