How to get brackets without apostrophes from the writeStream? - quotes

I tried to get my brakets back from the wirteStream. Sadly the writeStream set two punctuation marks (apostrophes) before and after the brackets.
Could someone help me? I found the mistake for this in the class String in printOn and mainly in storeOn.
Have you an idea to solve it? I thought on RegEx... but maybe someone has another methode or solution.
| stream |
'()' printOn: (stream := '' writeStream).
stream contents = '()'.
Regards,
bartak.

This is because String's #printOn: explicitly calls #storeOn:
printOn: aStream
"Print inside string quotes, doubling inbedded quotes."
self storeOn: aStream
You could do it the other way around:
(stream := '' writeStream) nextPutAll: '()'.

That's because String>>printOn: will print "a string as a string", i.e. it will be quoted again. Solution: don't use #printOn: but rather Stream>>nextPutAll: or Stream>>print:.
Clarification:
#print is supposed to be sent to the stream, not to ByteString:
'' writeStream print: '()'.

Related

How to split a string by slash in ruby

how can i split a string "DESKTOP-AHDESI\Username" by slash in ruby 2.7.1p83
tmp = "DESKTOP-AHDESI\Username"
print tmp
tmp = tmp.split("\\")
print tmp
i got:
Ruby Error: NoMethodError undefined method `gsub!'
Problem
Your tmp variable is enclosed in double-quotes, and contains a backslash which is being interpreted as an escape rather than a character literal. You can see this easily by simply pasting your string into a REPL like irb:
"DESKTOP-AHDESI\Username" #=> "DESKTOP-AHDESIUsername"
You need to handle the backslash specially in both your String methods.
Solution
One way to handle this is to use Ruby's alternate quoting mechanism. For example:
%q(DESKTOP-AHDESI\Username).split '\\' #=> ["DESKTOP-AHDESI", "Username"]
This may not help you directly, though.
Wherever the value from tmp is coming from, you need to refactor the code to ensure that your String is properly escaped before you assign it to your variable, or otherwise pre-process it. String#dump won't really help much if the value you're assigning is unescaped before assignment, so you're going to have to fix this in whatever code you're using to generate or grab the string in the first place.
First of all, you are giving the wrong string. \ is the escape character when you use inside the "". So It will try to escape the next character U but this character doesn't have any Job so it will print U on the screen. Modify your string like below, it will work.
tmp = "DESKTOP-AHDESI\\Username"
p tmp
tmp = tmp.split("\\")
p tmp
Output
"DESKTOP-AHDESI\\Username"
["DESKTOP-AHDESI", "Username"]

How to delete a substring after a certain word?

I have a long String and want to delete the part of the String that comes after a word and I'm looking for the gsub! command that does that. I would appreciate it if you could provide it.
For reference:
I know that the command to delete the part of the String (the String is called contents) that comes before the word "body" is:
contents.gsub!(/.*?(?=body)/im, "")
Thanks.
This code:
"this has a word in it".gsub! /(word).*/, $1
Will change the string to "this has a word"
The "word" in brackets is the first argument returned by the regex, and $1 returns that argument.
See the Ruby docs for gsub
Going by your regex, that requires the / in body to be escaped, I'm assuming you mean every after
contents = "Stuff before </body> stuff after"
contents.gsub(/(?<=\/body>).+/, "")
=> "Stuff before </body>"

start_with not working for backslash in ruby

I have the following string -
abcdefgh;
lmnopqrst;
On doing a string = string.split(";"), I get -
["abcdefgh", "\nlmnopqrst"]
Now when I do -
string[1].start_with?("\\")
The function returns false. Whereas if I do
string[0].start_with?("a")
The function return true.
I am new to ruby and just can't understand this behavior. Can anyone tell me what am I doing wrong.
I dont know, butString[1][0] (first character from string) returns "\n" so maybe use this
string[1].start_with?("\n")
This is because "\n" actually does not start with a backslash . It is the line feed character and is considered to be a single character and for that reason it is only presented having the escape character \ in front of it.
So:
string[1].start_with?("\n")
Will return true.
You already tried to search with string[1].start_with?("\\") so you seem to realize you need to escape the backslash character by using \\.
If your input string would look like this:
\abcdefgh;
lmnopqrst;
Then after .split(';') your resulting array would look like this:
["\\abcdefgh;", "\nlmnopqrst"]
Now string[0].start_with?("\\") would return true because the first string actually starts with a single backslash, which was presented with the escape character in the console.
you can try
'\nhello world'.start_with?("\\") # return true
"\nhello world".start_with?("\\") # return false
because '\n' is two chars( \ and n), but "\n" is one char(new line char).
The first character there is not "\" - it's "\n" in the first example, and "\\" in the second. "\n" and "\\" are effectively single characters in this context, even though they look like two characters.
"\n" != "\\", and so start_with? responds false.

Ruby regex: "capture string unless it is followed by..."

My regex captures quoted phrases:
"([^"]*)"
I want to improve it, by ignoring quotes, which are followed by ', -' (a comma, a space and a dash in this particular order).
How do I do this?
The test: http://rubular.com/r/xls6vN1w92
This should do it, using a Negative Lookahead:
"(?!, -)([^"]*)"(?!, -)
A little icky, but it works. You want to make sure either quote isn't followed by your string, or else the match will start at the closing quotes.
http://rubular.com/r/yFMyUKJOHL
Regex
"(.*?)"(?!, -)
Working Example
http://rubular.com/r/9kOmZLxLfy
This is unparsable in your context, its open ended. The only way to parse it is to consume the not's as well as the want's, but its still an invalid premise.
/"([^"]*?)"(?!, -)|"[^"]*?"(?=, -)/
Then check for capture group 1 on each match, something like this:
$rx = qr/"([^"]*?)"(?!, -)|"[^"]*?"(?=, -)/;
while (' "ingnore me", - "but not me" ' =~ /$rx/g) {
print "'$1'\n" if defined $1
}
Add (?!...) at the end of the regex:
"([^"\n]*)"(?!, -)

how to remove all [d+] except the last [d+]?

i have a string like
/root/children[2]/header[1]/something/some[4]/table/tr[1]/links/a/b
and
/root/children[2]/header[1]/something/some[4]/table/tr[2]
how can i reproduce the string so that all the /\[\d+\]/ are removed except for the last /\[\d+\]/ ?
so i should end up with .
/root/children/header/something/some/table/tr[1]/links/a/b
and
/root/children/header/something/some/table/tr[2]
No loops for you. Use a lookahead assertion (?= ... ):
s.gsub(/\[\d+\](?=.*\[)/, "")
There's a reasonable explanation of the very useful lookaround operators here
We will have to use while loop, I guess. And here comes good ol' C-style-loop solution:
while s.gsub!(/(\[\d+\])(.*?)(\[\d+\])/, '\2\3'); end
It's a bit hard to read, so I'll explain. The idea is that we match the string with a pattern that requires two [\d+] blocks to persist in a string. In the replacement, we just delete the first one. We repeat it until string doesn't match (so it contains only one such block) and utilize the fact that gsub! doesn't perform substitution when string is unmatched.
I'm absolutely certain there's a more elegant solution, but this ought to get you going:
string = "/root/children[2]/header[1]/something/some[4]/table/tr[1]/links/a/b"
count = string.scan(/\[\d+\]/).size
index = 0
string.gsub(/\[\d+\]/) do |capture|
index += 1
index == count ? capture : ""
end
Try this:
str.scan(/\[\d+\]/)[0..-2].each {|match| str.sub!(match, '')}

Resources