2014-02-16 4 views
7

Я действительно новичок в и хочу знать, можно ли проверить, содержит ли строка только положительные числа, используя или какую-то другую функцию?Проверьте, содержит ли строка только положительные числа в Ruby

str = "123abcd" #return false because it contains alphabets 
str = "153"  #return true because of all numbers 
+1

Под «положительными цифрами», я полагаю, вы имеете в виду 1-9. Это правильно, или вы имеете в виду «0-9» (в этом случае вы должны нанести «положительный»)? –

+0

Нет такой вещи, как «положительные цифры». Одна или несколько цифр выражают число. Число может быть положительным или нет. '0' сам выражает неположительное число. '0' в' 10' является частью положительного числа. Вы не можете сказать, является ли '0' цифрой положительной или нет. Точно так же «1» является положительным числом. '1' в' -1' является частью отрицательного числа. – sawa

+1

Я понял, что в исходном вопросе «положительные числа» и Уэйн отредактированы «позитивные цифры». Оригинальный был лучше. – sawa

ответ

5

Конечно Regexp хорош для этого:

string = "123abcd" 
/^(?<num>\d+)$/ =~ string 
num # => nil 

string = "123" 
/^(?<num>\d+)$/ =~ string 
num # => '123' # String 

Так что, если вам нужно проверить состояние:

if /^(?<num>\d+)$/ =~ string 
    num.to_i # => 123 
    # do something... 
end 

#to_i метод String не действителен для вашего случая, потому что он вернет число, если строка равно буквам:

string = "123abcd" 
string.to_i # 123 
+0

Он работает, но неэффективен. – sawa

+1

2nd downvoter вы слабы, чтобы объяснить это? –

+0

Не будет '/ [- +] * \ d /' также работать? Это намного проще – Zac

4
if '123'.match(/^\d+$/) 
    # code 
end 
+0

Это работает, но неэффективно. – sawa

+0

@sawa Можете ли вы объяснить, почему это менее эффективно, чем ваш отрицательный ответ? –

+0

@MarkThomas Когда строка содержит не цифру, моему регулярному выражению не нужно переносить информацию о подходящем кандидате, потому что (неправильное) соответствие определяется путем просмотра одного символа. Для применения шаблона просто нужно увеличить начальную позицию. Регулярное выражение в этом ответе должно отслеживать информацию о подходящем кандидате (последовательность цифр) до точки, в которой он терпит неудачу. – sawa

2

я сделать, используя Regexp#===, как показано ниже:

str = "123abcd" 
/^\d+$/ === str # => false # because string not only contains digits 
str = "153" 
/^\d+$/ === str # => true # because string only contains digits 

обновления (с учетом comment1 и comment2 @ Саввы)

str = "123abcd" 
/\D/ === str # => true # because string contains non-digit 
str = "153" 
/\D/ === str # => false # because string doesn't contain any non-digit 
+0

Он работает, но неэффективен. – sawa

+0

@sawa Спасибо за ваш отзыв. Не могли бы вы сказать, почему это эффективно? Спросить из любопытства. –

+1

Если строка содержит символ без цифр, в этой точке становится ясно, что он должен возвращать значение false, и нет необходимости смотреть дальше в строку. Но ваше регулярное выражение просматривает всю строку. – sawa

19

Всех других ответов до сих пор с помощью регулярных выражений являются неэффективными.

"123abcd" !~ /\D/ # => false 
"153" !~ /\D/  # => true 
+1

Итак, вы считаете, что все неотрицательные регулярные выражения неэффективны? Я думаю, что разница была бы незначительной для большинства случаев реального мира. –

+0

В дополнение к эффективности эти регулярные выражения сложнее. Нет причин для их использования. – sawa

+3

Согласен, и я проголосовал за ваш ответ из-за его простоты. Тем не менее, я не думаю, что я буду отмечать кого-либо в обзоре кода для использования '= ~' over '! ~'. Регулярные выражения по-прежнему довольно эффективны. «Менее эффективно»! = «Неэффективно». –

0

Первоначально я ответил на этот вопрос, когда «только положительные цифры» были требованием, но я вижу, что было изменено на «только положительные числа» (оригинальная формулировка), которая, в частности, из-за пример данных (что исключает интерпретацию "12abc34" => true, "12abc-34" => false и не предполагает интерпретации "1.5abc" => true), я подразумеваю «одно положительное целое число». Мое предположение сказано точнее мой ответ:

str =~ /^0*[1-9]\d*$/ 

Этот вопрос возникает другой: «Сколько Rubiests может танцевать на булавочной головке?». Может быть, это просто день новостей. Спасибо @sawa и @Mark за их комментарии.

+0

Логическая ошибка: возвращает 'истина' для пустой строки. Вы хотите '+'. –

+1

@ Mark, я обдумал это, но решил пойти с '*', поскольку я полагал, что искатель не имел в виду «только положительные цифры» буквально, так как если бы/она это сделала, можно было бы утверждать, что ложь должна быть возвращена для строк длины один, который, как я думаю, не был предназначен. Был ли ваш нисходящий голос? –

+1

Да, но я удалю его, если вы положите свою (полностью действительную) интерпретацию неустановленных требований в ответ. –

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