Как удалить непечатаемые невидимые символы из строки? - PullRequest
2 голосов
/ 25 апреля 2019

Как я могу удалить непечатаемые невидимые символы из строки?

Версия Ruby: 2.4.1

2.4.1 :209 > product.name.gsub(/[^[:print:]]/,'.')
 => "Kanha‬" 
2.4.1 :210 > product.name.gsub(/[^[:print:]]/,'.').length
 => 6 

2.4.1 :212 > product.name.gsub(/[\u0080-\u00ff]/, '').length
 => 6 

2.4.1 :214 > product.name.chars.reject { |char| char.ascii_only? and (char.ord < 32 or char.ord == 127) }.join.length
 => 6 

2.4.1 :216 > product.name.gsub(/[^[:print:]]/i, '').length
 => 6 

Слово "Kanha" состоит из 5 букв.Однако есть 6-й символ, который нельзя распечатать.Как я могу удалить его?

Путем поиска в Google и SOing я уже попробовал несколько подходов, но, как вы можете видеть, ни один из них не является полезным.

Это вызывает проблемы, когда я пытаюсь интегрироватьданные с другими системами.

1 Ответ

4 голосов
/ 26 апреля 2019

Во-первых, давайте выясним, что такое оскорбительный символ:

str = "Kanha‬"
p str.codepoints
# => [75, 97, 110, 104, 97, 8236]

Первые пять кодовых точек находятся в диапазоне от 0 до 127, что означает символы ASCII. Можно с уверенностью предположить, что это буквы K-a-n-h-a, хотя это легко проверить, если вы хотите:

p [75, 97, 110, 104, 97].map(&:ord)
# => ["K", "a", "n", "h", "a"]

Это означает, что последним символом является код нарушителя, кодовая точка 8236. Однако это десятичное число (основание 10), а символы Юникода обычно перечисляются по их шестнадцатеричному (основание 16) числу. 8236 в шестнадцатеричном виде это 202C (8236.to_s(16) # => "202c"), поэтому нам просто нужно Google для U + 202C .

Google очень быстро сообщает нам, что оскорбительный символ U + 202C POP DIRECTIONAL FORMATTING и что он является членом категории "Другие, формат" символов Unicode. Википедия говорит этой категории:

Включает в себя мягкий дефис, объединяющие управляющие символы (zwnj и zwj), управляющие символы для поддержки двунаправленного текста и символы языкового тега

Это также говорит нам, что «значением» или кодом для категории является «Cf». Если эти символы похожи на символы, которые вы хотите удалить из вашей строки вместе с U + 202C, вы можете использовать свойство \p{Cf} в регулярном выражении Ruby. Вы также можете использовать \P{Print} (обратите внимание на заглавную P) как эквивалент [^[:print]]:

str = "Kanha‬"
p str.length # => 6

p str.gsub(/\P{Print}|\p{Cf}/, '') # => "Kahna"
p str.gsub(/\P{Print}|\p{Cf}/, '').length # => 5

Смотрите на repl.it: https://repl.it/@jrunning/DutifulRashTag

...