2015-03-18 7 views
2

У меня есть несколько строк, которые содержат одну или несколько цифр, а также могут содержать одну или несколько букв, следующих за цифрами (колпачки на буквах не имеют значения). Строки следовать следующим регуляркам схемы:Разделить строку на строку и целое число

[0-9]+[a-zA-z]* 

и могут выглядеть следующим образом:

"15791" 
"14810A" 
"10480ABCD" 
"5ABCDEFGH" 

Если одна из строк выше, содержат нечисловые символы, как я разделить число (первая часть) в целое число и буквы (вторая часть) в строку?

Я знаю, что могу разделить строку, как это:

array = "1,2,3,4".split(',') 

Но это не помогает, так как у меня нет сепаратора.

+1

Хороший вопрос и хорошо написанный: лаконичный, полный, недвусмысленный. –

ответ

7

Используйте положительное выражение regex, основанное на утверждении lookbehind, в string.split.

> "10480ABCD".split(/(?<=\d)(?=[A-Za-z])/) 
=> ["10480", "ABCD"] 
  • (?<=\d) Положительный просмотра назад, утверждающий, что матч должен предшествовать символ цифры.

  • (?=[A-Za-z]), который утверждает, что за соответствием должен следовать алфавит. Таким образом, указанное выше регулярное выражение будет соответствовать границе, которая существует между цифрой и алфавитом. Разделение вашего ввода в соответствии с согласованной границей даст вам желаемый результат.

ИЛИ

Использование string.scan

> "10480ABCD".scan(/\d+|[A-Za-z]+/) 
=> ["10480", "ABCD"] 
+1

Ничего себе, это было срочно! Пробовал это в irb и работает как шарм! Большое спасибо, я отвечу на ответ через 12 минут :) – NickEckhart

+0

avinash, если строка будет иметь только цифры и алфавиты, лучше придерживаться '\ d' и' \ D', чтобы выражение было простым. как в моем ответе. :) – Humza

+0

op ясно указывает, что его строка должна удовлетворять шаблону '[0-9] + [a-zA-z] *'. Изменение '[A-Za-z] +' на '\ D +' не будет намного больше различий. –

0

Вы всегда можете использовать match:

re = /(\d+)([a-z]*)/i 
str = "10480ABCD" 

m = re.match(str) 
m #=> #<MatchData "10480ABCD" 1:"10480" 2:"ABCD"> 
m[0] #=> "10480" 
m[1] #=> "ABCD" 

Использование MatchData#[] для извлечения группы захвата:

re.match(str)[1, 2] 
["10480", "ABCD"] 
5

сплиттер является сам нечисловыми символами:

"10480ABCD".split(/(\D+)/) 
# => ["10480", "ABCD"] 
+0

Умный. Озадаченные читатели (если есть): одна строка документов для [String # split] (http://ruby-doc.org/core-2.2.0/String.html#method-i-split) гласит: «Если шаблон содержит группы [capture], соответствующие совпадения также будут возвращены в массиве ». –

0

[Edit: по какой-то причине @Humza удалил свой ответ, так что я восстановлен мой. Я уже писал, но потом удалил его, когда я заметил, что Humza уже отправил аналогичный ответ]

Я чувствую, что я должен быть что-то отсутствует, как это, кажется, есть простое решение:.

def extract(str) 
    str.scan(/\d+|[A-Z]+/i) 
end 

extract "15791"  #=> ["15791"] 
extract "14810A" #=> ["14810", "A"] 
extract "10480ABCD" #=> ["10480", "ABCD"] 
extract "5ABCDEFGH" #=> ["5", "ABCDEFGH"] 
Смежные вопросы