2011-11-09 3 views
1

Я тестирую две строки, чтобы убедиться, что они равны. Одна строка просто простая строка: "\17" Другой разбирается на: "\17"Ruby: Строки не совпадают

num = 7 
num2 = "\17" 

parsed_num = "\1#{num}" 

puts parsed_num.class 
puts num2.class 

if parsed_num == num2 
    puts 'Equal' 
else 
    puts 'Not equal' 
end 

возвращает:

String 

String 

Not equal 

Моя цель состоит в том, чтобы иметь parsed_num точно так же, как буквальное num2

ответ

3

I собираюсь взять противоположный ответ, и предположим, что «\ 17» является правильно, а затем рассмотреть this code:

num = 7 
num2 = "\17" 
puts "ni #{num2.inspect}" 

# extra \ to fix error, for demo 
parsed_num = "\\1#{num}" 
puts "pi #{parsed_num.inspect}" 

# for note, but ICK!!! 
p2 = eval('"' + parsed_num + '"') 
puts "p2i #{p2.inspect}" 
puts "p2= #{p2 == num2}" 

dec = (10 + num).to_s.oct 
p3 = dec.chr 
puts "p3i #{p3.inspect}" 
puts "p3= #{p3 == num2}" 

Результат:

ni "\017" 
pi "\\17" 
p2i "\017" 
p2= true 
p3i "\017" 
p3= true 

Причина, почему "\1#{num}" не работают, что строковые литералы - и встроенные управляющие последовательности - обрабатываются во время разбора в то время как сама строка интерполяции (#{}) происходит позже, при пробеге -время. (Это необходимо, потому что, кто знает, что может случиться, чтобы быть в num?)

В случае p2 я использовал eval, который разбирает, а затем выполняет прилагаемый код. Код там эквивалентен eval('"\17"'), потому что parsed_num содержит трехбуквенную строку: \17. (! Обратите внимание, что этот подход обычно считается плохим)

В случае p3 я вручную сделал то, что парсер для строки интерполяции \octal: взял значение из octal, в, ну, восьмеричной, а затем преобразует его в «символ» с соответствующим значением.

Счастливое кодирование.

+1

' p3.encoding' является 'US-ASCII', 'num2.encoding' является 'UTF-8', поэтому они не являются« точно такими же »в некотором смысле. –

+0

Спасибо. Он работает отлично. – user1038486

+0

@undur_gongor Спасибо, что указали это, я интериоризую: –

1

Используйте одинарные кавычки, чтобы вовлеченные строки были буквальными вещами, которые вы устанавливаете:

num = 7 
num2 = '\17' 

parsed_num = '\1' + String(num) 
if parsed_num == num2 
    puts 'Equal' 
else 
    puts 'Not equal' 
end 

Это производит «Равный» - желаемый результат. Here's a link с дополнительной информацией о различиях между одиночными кавычками и двойными кавычками, если это необходимо.

+0

Возможно ли, чтобы они были равны без изменения num2 – user1038486

3

Если вы используете «\ 17» обратный слэш побег, это будет интерпретироваться и как «\ 0017», где 17 будет восьмеричное цифра равна «F» Hex:

"\17" # => "\u000F" 

, потому что ваш string использует двойные кавычки.

Вы можете добиться того, что вы хотите с помощью этого фрагмента кода, например:

num = 7 
num2 = "\\17" 
parsed_num = "\\1#{num}" 
if parsed_num == num2 
    puts 'Equal' 
else 
    puts 'Not equal' 
end 
# => Equal 

Как вы можете видеть, вы получите этот результат с помощью обратной косой черты, чтобы избежать другой обратный слэш :)

+0

Можно ли получить оба равных без изменения num2 – user1038486

+0

Если вы измените 'parsed_num' с' "\ 1 # {num}" 'на' "\ xF" 'например, – WarHog

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