2010-04-06 21 views
26

Mam przypadki, w których dane wprowadzane przez użytkownika z textarea HTML lub danych wejściowych są czasami wysyłane z \u00a0 (spacje nierozdzielające) zamiast spacji, gdy są zakodowane jako json utf-8.Konwertuj niepodzielone spacje na spacje w Rubim

Uważam, że jest to błąd w Firefoksie, ponieważ wiem, że użytkownik nie zamierza celowo wprowadzać spacji nie zamiast spacji.

Istnieją również dwa błędy w Ruby, z których jeden może być użyty do walki z drugim.

Z jakiegokolwiek powodu \s nie pasuje do \u00a0.

Jednak [^[:print:]], które zdecydowanie nie powinny się zgadzać) i \xC2\xA0 oba będą pasować, ale uważam, że są to mniej niż idealne sposoby radzenia sobie z problemem.

Czy istnieją inne zalecenia dotyczące obejścia tego problemu?

+1

Która wersja Ruby? W wersji 1.9.2/\ u00a0/pasuje. – steenslag

+0

\ s nie pasuje \ u00a0 \ u00a0 mecze w 1.9, ale nie jestem pewien o 1.8 – CoolAJ86

+7

Zasada # 1: Gdy uważasz, że znalazłeś błąd w bardzo popularnym programie, zwłaszcza w coś, co jest testowane i szeroko stosowane, takie jak obsługa tekstur Firefoksa, bardzo cicho i starannie przechodzą testy. 99 razy na 100 problem będzie po twojej stronie płotu. Kiedy widzę spacje nierozdzielające się w polu tekstowym, gdzie prawdopodobnie wkleją tekst, podejrzewam, że Microsoft Word lub edytor ustawiony jako zastępujący   dla spacji. Możesz łatwo sprawdzić swoją teorię, tworząc stronę, umieść w niej obszar tekstowy i spróbuj zduplikować problem. –

Odpowiedz

1

Dla starych wersji ruby ​​(1.8.x), poprawki są opisane w pytaniu.

Naprawiono to w nowszych wersjach ruby ​​1.9+.

+0

Czy możesz uzyskać bardziej szczegółowe informacje? Właśnie miałem ten sam problem na 1.9.3p194, który jest dość 1.9ish. \ s nie pasuje do spacji Unicode, ale \ u00a0 robi. – nasmorn

2

Z jakiegokolwiek powodu \ s nie pasuje do \ u00a0.

Myślę, że "jakikolwiek powód" jest taki, do którego nie należy. Tylko klasy znaków konstruowania POSIX i \ p są znane z Unicode. Skróty charakter klasy nie są:

Sequence As[...]  Meaning 
    \d [0-9]   ASCII decimal digit character 
    \D [^0-9]   Any character except a digit 
    \h [0-9a-fA-F] Hexadecimal digit character 
    \H [^0-9a-fA-F] Any character except a hex digit 
    \s [ \t\r\n\f] ASCII whitespace character 
    \S [^ \t\r\n\f] Any character except whitespace 
    \w [A-Za-z0-9\_] ASCII word character 
    \W [^A-Za-z0-9\_] Any character except a word character 
+2

Och, to ** przypuszcza ** do, w porządku. Po prostu tak nie jest. Zobacz moją odpowiedź. – tchrist

+0

Jest różnica między tym, że jest w specyfikacji, a tym, że jest w kodzie. To, czy ma się tak ze względu na specyfikację, jest teraz kwestią sporną, ponieważ jej nie ma i nie ma znaczenia, jak bardzo chcemy, aby była na miejscu, dopóki ktoś z zespołu głównego nie zdecyduje się go dodać. . Tak więc rzeczywistość jest taka, że ​​nie powinna działać, ponieważ nie jest zakodowana. Może w przyszłych obrotach, które się zmienią. Chciałbym, żeby spełniały one specyfikacje, ale nie pytają mnie. –

+0

To naprawdę dziwne podejście do rzeczy. tchrist jest absolutnie poprawny, a powiedzenie, że coś "nie powinno działać", ponieważ obecnie nie działa, jest najlepszą bezsensowną prawdą, którą czytałem od jakiegoś czasu. Tak czy inaczej - gsub na [[: spacja:]], dopóki ktoś nie sprawi, że Ruby rzeczywiście będzie spełniać standardy. – owenmarshall

6

Jeśli nie można używać \s dla białych znaków Unicode, że to błąd w realizacji regex Ruby, ponieważ według UTS#18 “Unicode Regular Expressions” Annex C on Compatibility Properties\s jest absolutnie konieczne dopasować wszystkie spacje Unicode punkt kodowy.

Nie ma dozwolonej ilości miejsca na wiggle, ponieważ dwie kolumny wyszczególniają rekomendację standardową, a zgodność z POSIX jest taka sama dla przypadku \s. Nie możesz udokumentować tego w ten sposób: nie przestrzegasz Standardu Unicode, w szczególności z UTS # 18's RL1.2a, jeśli tego nie zrobisz.

Jeśli nie spełniasz RL1.2a, nie spełniasz wymagań poziomu 1, które są najbardziej podstawową i elementarną funkcjonalnością potrzebną do używania wyrażeń regularnych na Unicode. Bez tego jesteś prawie zagubiony. Oto dlaczego istnieją standardy. Moje wspomnienie jest takie, że Ruby również nie spełnia kilku innych wymagań poziomu 1. Dlatego możesz chcieć użyć języka programowania, który spełnia przynajmniej poziom 1, jeśli potrzebujesz obsługiwać Unicode za pomocą wyrażeń regularnych.

Należy pamiętać, że nie można użyć właściwości ogólnej kategorii kodu Unicode, takiej jak \p{Zs}, co oznacza \p{Whitespace}. Dzieje się tak dlatego, że właściwość Whitespace jest własnością pochodną, ​​a nie kategorią ogólną. Są w nim również zawarte znaki kontrolne, a nie tylko separatory.

2

Rzeczywiste przykłady kodu funkcjonowanie IRB, że odpowiedź na pytanie, z najnowszymi Rubiny (maj 2012)

Ruby 1.9

require 'rubygems' 
require 'nokogiri' 
RUBY_DESCRIPTION # => "ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]" 
doc = '<html><body> &nbsp; </body></html>' 
page = Nokogiri::HTML(doc) 
s = page.inner_text 
s.each_codepoint {|c| print c, ' ' } #=> 32 160 32 
s.strip.each_codepoint {|c| print c, ' ' } #=> 160 
s.gsub(/\s+/,'').each_codepoint {|c| print c, ' ' } #=> 160 
s.gsub(/\u00A0/,'').strip.empty? #true 

Ruby 1,8

require 'rubygems' 
require 'nokogiri' 
RUBY_DESCRIPTION # => "ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux]" 
doc = '<html><body> &nbsp; </body></html>' 
page = Nokogiri::HTML(doc) 
s = page.inner_text # " \302\240 " 
s.gsub(/\s+/,'') # "\302\240" 
s.gsub(/\302\240/,'').strip.empty? #true 
37

Zastosowanie /\u00a0/ dopasować Przestrzenie zrywania. Na przykład s.gsub(/\u00a0/, ' ') konwertuje wszystkie niepodzielone spacje na zwykłe spacje.

Użyj /[[:space:]]/, aby dopasować wszystkie spacje, w tym spację Unicode, jak spacje nierozdzielające. Jest to odmienne od /\s/, które pasuje tylko do białych znaków ASCII.

Zobacz także: Ruby Regexp documentation

+0

Spójrz na http://www.unicode.org/versions/Unicode6.2.0/ch06.pdf - Znaki spacji. Ale id nie wygląda na kompletny –

+0

Naprawiono moją odpowiedź, aby po prostu użyć '[[: space]]' (uwaga do siebie: nie '[: spacja]'). –

+0

"s.gsub (/ \ u00a0 /, '')" jest tym, czego szukałem. –

1

Chociaż nie związane z Ruby (a nie bezpośrednio do tej kwestii), rdzeń problemu może być że Alt + Przestrzeń na Mac produkuje non-breaking przestrzeń.

Może to powodować wszelkiego rodzaju dziwne zachowanie (szczególnie w terminalu).

Dla tych, którzy są zainteresowani większą ilością szczegółów, napisałem "Why chaining commands with pipes in Mac OS X does not always work" o tym temacie jakiś czas temu.