don't know why... but this is not working
a=" xxxxxx\tttt\3.4.2\uuuu"
puts a.gsub('\\','/')
And the result is:
xxxxxx ttt.4.2uuuu
what i want is xxxxxxx/tttt/3.4.2/uuuu
on 2013-02-21 11:26
on 2013-02-21 11:31
Subject: backslash substitution Date: gio 21 feb 13 07:26:23 +0900 Quoting Mario Ruiz (lists@ruby-forum.com): > don't know why... but this is not working > a=" xxxxxx\tttt\3.4.2\uuuu" > puts a.gsub('\\','/') There has been a recent thread about this. You string should be defined as. a=" xxxxxx\\tttt\\3.4.2\\uuuu" Carlo
on 2013-02-21 11:33
Yes I know.. but i cannot change the string... the string it is like it is... so i need to modify it later on and that's the problme Carlo E. Prelz wrote in post #1098178: > Subject: backslash substitution > Date: gio 21 feb 13 07:26:23 +0900 >
on 2013-02-21 11:40
Subject: Re: backslash substitution Date: gio 21 feb 13 07:33:50 +0900 Quoting Mario Ruiz (lists@ruby-forum.com): > Yes I know.. but i cannot change the string... the string it is like it > is... so i need to modify it later on and that's the problme ? If you substitute characters, you change the string. Carlo
on 2013-02-21 11:48
you mean by using gsub... in the expample i posted i tried but didn't work Carlo E. Prelz wrote in post #1098182: > > If you substitute characters, you change the string. >
on 2013-02-21 11:54
Subject: Re: backslash substitution Date: gio 21 feb 13 07:48:43 +0900 Sorry for the delay! Quoting Mario Ruiz (lists@ruby-forum.com): > you mean by using gsub... in the expample i posted i tried but didn't > work irb(main):002:0> a=" xxxxxx\\tttt\\3.4.2\\uuuu" => " xxxxxx\\tttt\\3.4.2\\uuuu" irb(main):003:0> puts a.gsub('\\','/') xxxxxx/tttt/3.4.2/uuuu => nil What does not work? PS: irb(main):004:0> a="\\a\\b" => "\\a\\b" irb(main):005:0> a.length => 4 irb(main):006:0> a.chars => ["\\", "a", "\\", "b"] irb(main):007:0>
on 2013-02-21 11:57
I cannot modify the string by myself... the string it is like it is... is given as an argument so i cannot modify it by writing doubles
on 2013-02-21 12:21
On 21.02.2013 10:57, Mario Ruiz wrote: > I cannot modify the string by myself... the string it is like it > is... > is given as an argument so i cannot modify it by writing doubles Carlo's point is that your string as it stands does not contain any backslashes. E.g. >> a=" xxxxxx\tttt\3.4.2\uuuu" => " xxxxxx\tttt\003.4.2uuuu" >> puts a xxxxxx ttt.4.2uuuu => nil So your attempt to substitute them is destined to fail.
on 2013-02-21 12:31
I think doing this in irb might help illuminate the issue. Please read
the whole thing, and then read it again, and then if you think you
understand it, read it again and type along in your own ruby/irb.
irb(main):001:0> a=" xxxxxx\tttt\3.4.2"
=> " xxxxxx\tttt\x03.4.2"
I now have a string, called `a`. It has some characters in. You may
notice that in my 1.9.2 Ruby the "\3" becomes "\x03" when inspected.
Interesting. (I suspect that in 1.8 it would have become "\03", but I
can't remember that far back to be certain.)
irb(main):002:0> a.unpack('C*')
=> [32, 120, 120, 120, 120, 120, 120, 9, 116, 116, 116, 3, 46, 52, 46,
50]
All I'm doing here is extracting the integer values of each ASCII
character in my `a` string. Did you note that there are 16
bytes/characters, even though I typed 18 characters between the quotes
in my original statement? Note also that the eighth byte, corresponding
with my first backslash, has the value 9. I happen to know that 9 is
actually the ASCII TAB character, which is usually referred to as "\t".
I hope some bells are ringing here.
Odd, let me convert those integer byte values into strings, one by one,
so we can see them in a different way.
irb(main):003:0> a.unpack('C*').map{|int| int.chr }
=> [" ", "x", "x", "x", "x", "x", "x", "\t", "t", "t", "t", "\x03",
".", "4", ".", "2"]
Each string contains a single character. Notice how Ruby has
represented 9 as "\t" and 3 as "\x03", which look to be more than one
character each? That representation goes both ways (i.e. you may
require multiple characters of source code to represent a single
character of actual data.)
Now let's have a look at the gsub bit:
irb(main):004:0> '\\'
=> "\\"
irb(main):005:0> '\\'.unpack('C*')
=> [92]
irb(main):006:0> '\\'.unpack('C*').map{|int| int.chr }
=> ["\\"]
You can see quite plainly that ruby interprets the '\\' as a single
byte, with value 92, that is the ASCII backslash character.
Looking at the earlier code, there are no 92-bytes in the original
string. I must infer, then, that gsub is quite correctly replacing 100%
of those 92-characters with a forward slash. (In case you missed it,
100% of 0 is 0.)
Here is a little further experimentation on my part:
irb(main):006:0> b=" xxxxxx\\tttt\\3.4.2"
=> " xxxxxx\\tttt\\3.4.2"
irb(main):007:0> b.unpack('C*')
=> [32, 120, 120, 120, 120, 120, 120, 92, 116, 116, 116, 116, 92, 51,
46, 52, 46, 50]
Ahh, now `b` contains 18 characters, which is what we thought should
have been in `a`. To achieve this, I had to actually type _20_
characters between the double-quotes (doubling up the backslashes.)
See how the eighth byte is now 92? And so...
irb(main):008:0> b.gsub('\\', '/')
=> " xxxxxx/tttt/3.4.2"
Aha!
Therefore, since `a` is apparently "like it is" and can't be changed, I
would first be asking: what is it actually like? Does it contain
backslash characters, or does it contain TAB characters? You can find
this out fairly easily by adding the equivalent of:
STDERR.puts a.unpack('C*').inspect
..immediately before your current `gsub`. Then, if there are 92s in the
array, your gsub should be working, and our debugging effort should move
elsewhere.
However, if there are 9s in the array, then you have some serious
issues, because it means that someone who meant to put 92s into their
string actually put 9s and 3s and whatever other rubbish in there. It's
rather tricky (or impossible) to get them back out.
Let me leave you with a simple illustration:
irb(main):009:0> a="bbb\aaa\7.6.5"
=> "bbb\aaa\a.6.5"
irb(main):010:0> a.unpack('C*')
=> [98, 98, 98, 7, 97, 97, 7, 46, 54, 46, 53]
Oh noes! When I type "\a" and "\7" Ruby interprets them both as the
same thing! I have no way to "fix up" those integer 7s to either "\\a"
or "\\7" because by the time it looks like a 7, I have no way of knowing
which it was originally meant to be.
If you're in this situation, you need to go smack whoever messed up the
string in the first place. IMO
on 2013-02-22 04:41
On Thu, Feb 21, 2013 at 5:32 AM, Matthew Kerwin <lists@ruby-forum.com> wrote: > can't remember that far back to be certain.) > actually the ASCII TAB character, which is usually referred to as "\t". > represented 9 as "\t" and 3 as "\x03", which look to be more than one > irb(main):005:0> '\\'.unpack('C*') > 100% of 0 is 0.) > > > > => [98, 98, 98, 7, 97, 97, 7, 46, 54, 46, 53] > Posted via http://www.ruby-forum.com/. > Try your experiment again, only instead of wrapping the string with backslashes in double quotes, wrap it in single quotes. If the string coming in is unchangeable, experimenting using double quotes initially is incorrect, as that will interpolate. irb(main):011:0> a = "xxxxxx\tttt\3.4.2\uuuu" SyntaxError: (irb):11: invalid Unicode escape a = "xxxxxx\tttt\3.4.2\uuuu" ^ from /home/tamara/.rvm/rubies/ruby-1.9.3-head/bin/irb:16:in `<main>' irb(main):012:0> a = 'xxxxxx\tttt\3.4.2\uuuu' "xxxxxx\\tttt\\3.4.2\\uuuu" irb(main):013:0> a.gsub('\\','/') "xxxxxx/tttt/3.4.2/uuuu"
on 2013-02-22 07:51
Am 21.02.2013 11:26, schrieb Mario Ruiz: > don't know why... but this is not working > a=" xxxxxx\tttt\3.4.2\uuuu" > puts a.gsub('\\','/') > > And the result is: > xxxxxx ttt.4.2uuuu > > what i want is xxxxxxx/tttt/3.4.2/uuuu Your example string does not contain any backslashes! Instead it contains for example a tab: [1] pry(main)> puts "a\tb" a b You need to define the string using single quotes: [2] pry(main)> puts 'a\tb' a\tb Backslashes are interpreted differently in String literals with single and double quotes.
on 2013-02-22 09:47
The problem is I cannot put single or doubles since the value is given
as an argument in command line so the value is taken something like
this:
ARGV.each do |x|
if !x["folder="].nil? then a=x.gsub("folder=","") end
end
on 2013-02-22 10:09
Subject: Re: backslash substitution Date: ven 22 feb 13 05:47:17 +0900 Quoting Mario Ruiz (lists@ruby-forum.com): > The problem is I cannot put single or doubles since the value is given > as an argument in command line so the value is taken something like > this: > > ARGV.each do |x| > if !x["folder="].nil? then a=x.gsub("folder=","") end > end You still did not get it... A backslash is used to quote the following character so it transforms it into a non-printable character. For example: "\t" is a tab (ONE character, ascii 9) "\b" is a backspace (ONE character, ascii 8) "\a" is a bell character (ONE character, ascii 7) "\e" is an escape (ONE character, ascii 27) AND "\\" is a backslash (ONE character, ascii 92) I don't know what else to write... Carlo
on 2013-02-22 10:26
I found this solution... but i thought that Ruby had a better way:
x="xxxxx P jjjjjj\0\1\2\3.4.1\4\5\6\7\8\9"
m=""
x.each_byte {|a|
if a<32 then
m+="/" + a.to_s()
else
m+=a.chr
end
}
puts m
on 2013-02-22 10:36
Mario Ruiz wrote in post #1098396: > The problem is I cannot put single or doubles since the value is given > as an argument in command line so the value is taken something like > this: > > ARGV.each do |x| > if !x["folder="].nil? then a=x.gsub("folder=","") end > end Aha! Now some of what you've said starts to make sense. I just created this file: #test.rb: a=nil ARGV.each do |x| if !x["folder="].nil? then a=x.gsub("folder=","") end end p a When I run it in Windows, I get this: > ruby test.rb nil > ruby test.rb folder=a\b\c "a\\b\\c" So you can see that the Windows command prompt has interpreted the single backslashes as backslashes, and passed them through to Ruby faithfully. If I run it in Linux I get this: $ ruby test.rb nil $ ruby test.rb folder=a\b\c "abc" $ ruby test.rb folder=a\\b\\c "a\\b\\c" So you can see that bash (the command prompt I use) has interpreted the backslashes as special characters, not entirely unlike the way ruby would. However bash (and most *nix shells) give you options like this: $ ruby test.rb folder="a\b\c" "a\\b\\c" $ ruby test.rb folder='a\b\c' "a\\b\\c" The gsub line in Ruby would work just fine, but you also have to tell your _command prompt_ what you mean when you write a backslash.
on 2013-02-22 10:38
On 22.02.2013 09:27, Mario Ruiz wrote: > m+=a.chr > end > } > puts m Has that really done what you want though? >> puts m xxxxx P jjjjjj/0/1/2/3.4.1/4/5/6/789
on 2013-02-22 10:43
Yep I have it... if anyone knows a simpler way... post it ;) Thanks for your help
on 2013-02-22 10:51
Mario Ruiz wrote in post #1098399: > I found this solution... but i thought that Ruby had a better way: > > x="xxxxx P jjjjjj\0\1\2\3.4.1\4\5\6\7\8\9" > m="" > x.each_byte {|a| > if a<32 then > m+="/" + a.to_s() > else > m+=a.chr > end > } > puts m If you persist on pushing down this path, indeed Ruby does have a better way. Several. Legion. For example, and off the top of my head: x.gsub(/[\x00-\x1F]/){|c|"\\#{c.ord}"} However, and I'll say this one last time, your test code is FAULTY. It doesn't reflect the case you're trying to test. Have a look really closely at the "\8\9" part, have a look how that's interpreted by Ruby. Use the code snippets I so caringly wrote and demonstrated earlier. And then, try reverse-engineering this string using your method: x="c:\a\b\e\xface" If you want to test your gsub line and make sure it's replacing slashes with other slashes, either try it by putting it inside the actual ARGV.each block, or give it some input that matches what ARGV actually contains. If your ARGV contains rubbish, fix it at the calling context.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.