2016-05-08 7 views
3

Ищите регулярное выражение для использования с #gsub в Ruby, чтобы удалить все цифры в строке, за исключением ординалов. Предположим следующее прекрасно, чтобы сохранить то, что я хочу в строке:regex strip все цифры, кроме ординалов

string = "100 red balloons" 
strip_digits = string.gsub(/[^a-zA-Z\s]/, '') 
=> " red balloons" 

Как будет идти об изменении регулярных выражений в strip_digits, что если:

string = "50th red balloon" 

strip_digits вернется:

=> "50th red balloon" 

То есть, регулярное выражение будет игнорировать цифры, которые являются частью ординалов, в то же время сопоставляя их.

В этом примере можно с уверенностью предположить, что любая цифра, за которой следует порядковый указатель («nd», «th», «rd» или «st»), является порядковым номером.

+0

Итак, вы хотите удалить все во второй и третьей строках? – sawa

+1

Если вам просто нужно настроить ваше регулярное выражение, вы можете использовать ['gsub (/ (\ d + (?: th | [rn] d | st)) | [^ az \ s]/i," \\ 1 ") '] (http://ideone.com/XBHz3o) –

+0

Как вы собираетесь сказать, является ли письмо, следующее за цифрой, частью ординала или чего-то еще? Например, в 'TP-Link TL-WR1043ND'. – sawa

ответ

1

Подобно тому, как "исправить" ваше регулярное выражение, я предлагаю:

input.gsub(/(\d+(?:th|[rn]d|st))|[^a-z\s]/i, "\\1") 

См IDEONE demo here

Логика следующая: совпадение и захват в группу 1 все числа, сопровождаемые порядковыми числами s uffixes, а затем восстановить это значение с помощью обратной ссылки \1 в шаблоне замены, а затем сопоставить (для удаления) все не-буквы и не-пробелы с [^a-z\s] (или [^\p{L}\s]). Подробности

шаблон:

  • (\d+(?:th|[rn]d|st)) - Группа 1 соответствия 1+ цифры (\d+), а затем либо th, rd, nd или st (все подстроки хранится в пронумерованном буфера # 1, то есть доступ, когда \1 обратная ссылка используется в схеме замещения)
  • | - или
  • [^a-z\s] - символ, отличный от буквы ASCII (все нижние и верхние буквы сопоставляются из-за модификатора, нечувствительного к регистру /i) и пробела (чтобы избежать удаления букв Unicode, используйте \p{L} вместо a-z).
+0

, потому что '(th | rd | nd | st)' слишком длинный и читаемый – sweaver2112

0

Вы можете использовать word boundaries\b, т.е .:

strip_digits = string.gsub(/\b\d+(?!st|th|rd|nd)\b/, '') 

Regex объяснение:

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

Assert position at a word boundary (position preceded or followed—but not both—by a Unicode letter, digit, or underscore) «\b» 
Match a single character that is a “digit” (ASCII 0–9 only) «\d+» 
    Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+» 
Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?!st|th|rd|nd)» 
    Match this alternative (attempting the next alternative only if this one fails) «st» 
     Match the character string “st” literally (case sensitive) «st» 
    Or match this alternative (attempting the next alternative only if this one fails) «th» 
     Match the character string “th” literally (case sensitive) «th» 
    Or match this alternative (attempting the next alternative only if this one fails) «rd» 
     Match the character string “rd” literally (case sensitive) «rd» 
    Or match this alternative (the entire group fails if this one fails to match) «nd» 
     Match the character string “nd” literally (case sensitive) «nd» 
Assert position at a word boundary (position preceded or followed—but not both—by a Unicode letter, digit, or underscore) «\b» 

Regex101 Demo

+0

OP писал «ординалы (включая« st »и« nd »ординалы), что означает, что существуют другие аффиксы. – sawa

+0

@sawa *** «В этом примере можно с уверенностью предположить, что любая строка цифр, за которой следует последовательный указатель (« nd »,« th »,« rd »или« st »), является порядковым номером». * ** –

+0

Вы проигнорировали ответ, не понимая вопроса. –

0

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

t = "And on 3rd day, he created the 1st of his 22 books, not including the 3 that were never published - this was the 2nd time this happened." 
print(t.gsub(/\s*\d+(?!st|th|rd|nd)\s*/, " "))#=>And on 3rd day, he created the 1st of his books, not including the that were never published - this was the 2nd time this happened. 

IDEONE demo

Смежные вопросы