Feature #7845

Strip doesn't handle unicode space characters in ruby 1.9.2 & 1.9.3 (does in 1.9.1)

Added by Timothy Garnett about 1 year ago. Updated 12 months ago.

[ruby-core:52215]
Status:Open
Priority:Normal
Assignee:-
Category:-
Target version:-

Description

Strip and associated methods in ruby 1.9.2 and 1.9.3 do not remove leading/trailing unicode space characters (such as non-breaking space \u00A0 and ideographic space \u3000) unlike ruby 1.9.1. I'd expect the 1.9.1 behavior. Looking at the underlying native lstrip! and rstrip! methods it looks like this is because 1.9.1 uses rbencisspace() whereas 1.9.2+ uses rb_isspace().

1.9.1p378 :001 > "\u3000\u00a0".strip
=> ""

1.9.2p320 :001 > "\u3000\u00a0".strip
=> "  "

1.9.3p286 :001 > "\u3000\u00a0".strip
=> "  "


Related issues

Related to ruby-trunk - Feature #2093: String#stripの対象は\sか[:space:]か Closed 09/13/2009

History

#1 Updated by Koichi Sasada about 1 year ago

  • Subject changed from Strip doesn't handle unicode space characters in ruby 1.9.2 & 1.9.3 (does in 1.9.1) to Strip doesn't handle unicode space characters in ruby 1.9.2 & 1.9.3 (does in 1.9.1)
  • Category set to M17N
  • Assignee set to Yui NARUSE

#2 Updated by Yui NARUSE about 1 year ago

  • Subject changed from Strip doesn't handle unicode space characters in ruby 1.9.2 & 1.9.3 (does in 1.9.1) to Strip doesn't handle unicode space characters in ruby 1.9.2 & 1.9.3 (does in 1.9.1)
  • Status changed from Open to Rejected

#3 Updated by Timothy Garnett about 1 year ago

I'm not sure how convincing the linked conversation is. It seems to be about case sensitivity issues in varying locales particularly around identifiers, but whether a unicode space is a whitespace or not is not locale dependent as far as I know. It seems like strip, which is just whitespace, could easily be encoding aware while upcase/downcase and the like were ascii only for the cited complexity reasons.

It would be nice if strip removed the equivalent of :space: as it used to, but I guess that's what open source is for. If anyone stumbling upon this wants to patch ruby itself to restore the old behavior see https://gist.github.com/tgarnett/5032660 for ruby source or you can monkey patch in a fix to string

class String
def lstrip
sub(/:space:+/, '')
end
def rstrip
sub(/:space:+$/, '')
end
def strip
lstrip.rstrip
end
# etc. for ! versions
end

#4 Updated by James Darling about 1 year ago

I'm not sure I understand the rationale behind rejecting this issue based on locale issues. I'm in support of this ticket, and will try and grab someone who can respond to naruse's concerns.

#5 Updated by Paul Battley about 1 year ago

It's true that whitespace can be locale-dependent, at least insofar as Unix locales can specify which codepoints are to be considered as whitespace (in addition to space, tab, etc.).

The linked conversation about capitalisation doesn't seem relevant, though. The problem with capitalisation is that it really is language-specific: uppercase i is not I in Turkish, for example. Space, on the other hand isn't; it's just that the inventory of spaces used and their encoding depends on the locale: you won't find a double-width space in English, and the representation in UTF-8 and EUC-JP is different.

However, given that String#upcase/downcase are basically useless for non-ASCII content, I'm not sure I'd expect strip to handle Unicode spaces either.

#6 Updated by Marc-Andre Lafortune about 1 year ago

  • Status changed from Rejected to Open
  • Target version set to 2.1.0

Let's reopen this issue.

Yui: could you explain why strip wouldn't remove leading and trailing /\p{space}/ ? I can only see upside to this, but maybe you can point out downside?

#7 Updated by Timothy Garnett 12 months ago

A patch for this is pretty straightforward, see https://gist.github.com/tgarnett/5032660 which is only a couple of lines.

As someone dealing with a lot of web crawling and chinese source data, having strip remove non-breaking / ideographic spaces is a real boon (particularly given the large amount of code we have originally written to 1.9.1).

#8 Updated by Yui NARUSE 12 months ago

  • Status changed from Open to Rejected

marcandre (Marc-Andre Lafortune) wrote:

Let's reopen this issue.

Yui: could you explain why strip wouldn't remove leading and trailing /\p{space}/ ? I can only see upside to this, but maybe you can point out downside?

Did you read ?

#9 Updated by Marc-Andre Lafortune 12 months ago

  • Status changed from Rejected to Open
  • Assignee deleted (Yui NARUSE)

naruse (Yui NARUSE) wrote:

Did you read ?

I did.

Out of respect, I will assume that you read which explains nicely that has absolutely nothing to do with what constitutes a space and how strip should behave.

It would have been appreciated if instead of repeating your reference (which some of us believe not to be relevant) you would explain why you still feel it is of any relevance. This would be the helpful and polite thing to do.

I would also appreciate if you answered my questions too. For your convenience:

Yui: could you explain why strip wouldn't remove leading and trailing /\p{space}/ ? I can only see upside to this, but maybe you can point out downside?

Finally, could you please tell me why you rejected again this issue? Maybe if some people disagree with you, including a fellow committer, maybe the right thing to do is to explain yourself and ask Matz for his decision instead, would you not agree?

#10 Updated by Yukihiro Matsumoto 12 months ago

Five yeas have passed since the decision in , and Unicode had almost taken over the world.
Maybe it's time to relax the limitation at least when we are using Unicode.

Matz.

#11 Updated by Yui NARUSE 12 months ago

  • Tracker changed from Bug to Feature
  • Project changed from ruby-trunk to CommonRuby
  • Category deleted (M17N)
  • Target version deleted (2.1.0)

#12 Updated by Yui NARUSE 12 months ago

Current string-related policy is ASCII-based.
If it is changed, how wide it is applied is the issue; for example
* strip
* split
* upcase/downcase

#13 Updated by Yukihiro Matsumoto 12 months ago

Everything that can be resolved without locale/language information (for most of the cases).
Case conversion may have problems with some characters, e.g. german eszett or turkish i, but can be converted mostly.
Of course it would take time to implement everything, but the basic principle (and goal) will be.

Matz.

#14 Updated by Akira Tanaka 12 months ago

2013/5/6 matz (Yukihiro Matsumoto) matz@ruby-lang.org:

Everything that can be resolved without locale/language information (for most of the cases).
Case conversion may have problems with some characters, e.g. german eszett or turkish i, but can be converted mostly.
Of course it would take time to implement everything, but the basic principle (and goal) will be.

Be careful about network libraries.

Text based network protocol itself is not Unicode based in general.
If a primitive used in a such library is extended to Unicode, it may
cause mismatch to the protocol.

For example, the result of "grep -r strip lib/net" should be examined to
strip is used properly or not.
--
Tanaka Akira

#15 Updated by Yukihiro Matsumoto 12 months ago

Akira, Thank you for pointing out.

But it's hard for me to imagine concrete problematic cases.
When text from network connection is marked as Unicode, that's OK to process them as Unicode text,
otherwise they should be marked as 'ASCII-8BIT' so that #strip and other methods should behave as
they are now.

Matz.

#16 Updated by Yui NARUSE 12 months ago

matz (Yukihiro Matsumoto) wrote:

Akira, Thank you for pointing out.

But it's hard for me to imagine concrete problematic cases.
When text from network connection is marked as Unicode, that's OK to process them as Unicode text,
otherwise they should be marked as 'ASCII-8BIT' so that #strip and other methods should behave as
they are now.

Matz.

Modern protocol like SMTPUTF8 http://tools.ietf.org/html/rfc6532 and URL Standard http://url.spec.whatwg.org/
use UTF-8 as its character encoding, but they use ASCII whitespace.

#17 Updated by Yukihiro Matsumoto 12 months ago

=begin
Thank you for valuable input.

That indicates the need for something like (({str.strip(:ascii)})), or opposite (({str.strip(:utf8)}))

Matz.
=end

Also available in: Atom PDF