Replace \\n \\r \\t posted in rails - ruby-on-rails

I have a inout text field where user can copy paste data, I want to replace \r \n \t but when the data is posted these characters are escaped.
So a string entered by user for example hello \r\n\t world is posted as hello \\r\\n\\t world
I want to replace these characters but because they are escaped I am not able to use something like gsub(/\s+/, ' ')
Can anyone suggest what would be a ideal way to replace the escaped characters.
Thanks.

If you're getting literally backslash-r you'll need to de-map these:
CONVERT = {
'\r' => "\r",
'\t' => "\t",
'\n' => "\n"
}
CONVERT_RX = Regexp.union(CONVERT.keys)
'this\nis\tinput\r\n'.gsub(CONVERT_RX, CONVERT)
# => "this\nis\tinput\r\n"
You can add more entries to that table as necessary.
From there if you want to strip or convert spaces you can do that as you would normally.

Related

Leading and trailing spaces for each line from textarea

ruby 2.1.3
rails 4.1.7
I want to generate a unordered list from textarea. So I have to preserve all line breaks for each item and remove leading and trailing spaces.
Well, I'm trying to remove all leading and trailing spaces from each line of textarea with no success.
I'm using a regex:
string_from_textarea.gsub(/^[ \t]+|[ \t]+$/, '')
I've tried strip and rstrip rails methods with no luck too (they are working with the same result as regex):
Leading spaces for each line are removed perfectly.
But with trailing spaces only the last space from string is removed. But I wanna for each line.
What am I missing here? What is the deal with textarea and trailing spaces for each line?
UPDATE
Some code example:
I'm using a callback to save formated data.
after_validation: format_ingredients
def format_ingredients
self.ingredients = #ingredients.gsub(/^[ \t]+|[ \t]+$/, "")
end
Form view:
= f.text_area :ingredients, class: 'fieldW-600 striped', rows: '10'
You can use String#strip
' test text with multiple spaces '.strip
#=> "test text with multiple spaces"
To apply this to each line:
str = " test \ntext with multiple \nspaces "
str = str.lines.map(&:strip).join("\n")
"test\ntext with multiple\nspaces"
This isn't a good use for a regexp. Instead use standard String processing methods.
If you have text that contains embedded LF ("\n") line-ends and spaces at the beginning and ends of the lines, then try this:
foo = "
line 1
line 2
line 3
"
foo # => "\n line 1 \n line 2\nline 3\n"
Here's how to clean the lines of leading/trailing white-space and re-add the line-ends:
bar = foo.each_line.map(&:strip).join("\n")
bar # => "\nline 1\nline 2\nline 3"
If you're dealing with CRLF line-ends, as a Windows system would generate text:
foo = "\r\n line 1 \r\n line 2\r\nline 3\r\n"
bar = foo.each_line.map(&:strip).join("\r\n")
bar # => "\r\nline 1\r\nline 2\r\nline 3"
If you're dealing with the potential of having white-space that contains other forms of white-space like non-breaking spaces, then switching to a regexp that uses the POSIX [[:space:]] character set, that contains white-space used in all character sets. I'd do something like:
s.sub(/^[[:space:]]+/, '').sub(/[[:space:]]+$/, '')
I think #sin probably intimated the problem in his/her first comment. Your file was probably produced on a Windows machine that puts a carriage return/life feed pair ("\r\n") at the end of each line other than (presumably) the last, where it just writes \n. (Check line[-2] on any line other than the last.) That would account for the result you are getting:
r = /^[ \t]+|[ \t]+$/
str = " testing 123 \r\n testing again \n"
str.gsub(r, '')
#=> "testing 123 \r\ntesting again\n"
If this theory is correct the fix should be just a slight tweak to your regex:
r = /^[ \t]+|[ \t\r]+$/
str.gsub(r, '')
#=> "testing 123\ntesting again\n"
You might be able to do this with your regex by changing the value of the global variable $/, which is the input record separator, a newline by default. That could be a problem for the end of the last line, however, if that only has a newline.
I think you might be looking for String#lstrip and String#rstrip methods:
str = %Q^this is a line
and so is this
all of the lines have two spaces at the beginning
and also at the end ^`
`> new_string = ""
> ""
str.each_line do |line|
new_string += line.rstrip.lstrip + "\n"
end
> "this is a line\n and so is this \n all of the lines have two spaces at the beginning \n and also at the end "
2.1.2 :034 > puts new_string
this is a line
and so is this
all of the lines have two spaces at the beginning
and also at the end
> new_string
`> "this is a line\nand so is this\nall of the lines have two spaces at the beginning\nand also at the end\n"`

Why doesn't this regex match in ruby but matches in any other language?

The following works on Rubular.com but doesn't seem to match in ruby:
The string:
str = "<em>really</em>inexpensive"
Objective:
Add a space after any closing tag without any space after it.
The regex:
str.gsub("/(<\/[a-zA-Z]+>)(\S)/","\1 \2")
It should give back "<em>really</em> inexpensive"
You should use regular expression literal (/.../), not string ("..."). And escape the \ in the replacement string. (I used single-quote version of string in the following example)
str = "<em>really</em>inexpensive"
str.gsub(/(<\/[a-zA-Z]+>)(\S)/, '\1 \2') # '\1 \2' == "\\1 \\2"
# => "<em>really</em> inexpensive"

How can I replace new lines with \n character

Data stored in the database is like this:
This is a line
This is another line
How about this line
When I output it to the view, I want to convert that to:
This is a line\n\nThis is another line\n\nHow about this line
with no new lines and the actual \n characters printed out. How can I do that?
> s = "hi\nthere"
> puts s
hi
there
> puts s.gsub(/\n/, "\\n")
hi\nthere
I would personally use gsub if you only want newlines specifically converted. However, if you want to generally inspect the contents of the string, do this:
str = "This is a line\n\nThis is another line\n\nHow about this line"
puts str.inspect[1..-2]
#=> This is a line\n\nThis is another line\n\nHow about this line
The String#inspect method escapes various 'control' characters in your string. It also wraps the string with ", which I've stripped off above. Note that this may produce undesirable results, e.g. the string My name is "Phrogz" will come out as My name is \"Phrogz\".
> s = "line 1\n\nline2"
=> "line 1\n\nline2"
> puts s
line 1
line2
> puts s.gsub("\n", "\\n")
line 1\n\nline2
The key is to escape the single backslash.

Character encoding conversion

I have a string which contains Swedish characters and want to convert it to basic English.
name = "LänödmåtnÖng ÅjädårbÄn"
These characters should be converted as follows:
Å use A
å use a
Ä use A
ä use a
Ö use O
ö use o
Is there a simple way to do it? If I try:
ascii_to_string = name.unpack("U*").map{|s|s.chr}.join
It returns L\xE4n\xF6dm\xE5tn\xD6ng \xC5j\xE4d\xE5rb\xC4n as ASCII, but I want to convert it to English.
Using OP's conversion table as input for the tr method:
#encoding: utf-8
name = "LänödmåtnÖng ÅjädårbÄn"
p name.tr("ÅåÄäÖö", "AaAaOo") #=> "LanodmatnOng AjadarbAn"
Try this:
string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.to_s
As found in this post.
You already got decent answer, however there is a way that is easier to remember (no magical regular expressions):
name.parameterize
It changes whitespaces to dashes, so you need to handle it somehow, for example by processing each word separately:
name.split.map { |s| s.parameterize }.join ' '

Removing lines that begin with > in a rails string

I'm trying to remove any lines that begin with the character '>' in a long string (i.e. replies to an email).
In PHP I'd iterate over each line with an if statement, in linux I'd try and use sed or awk.
What's the most elegant rails approach?
You can try this:
your_string.gsub(/^\>.+\n/,'')
Your question is implying that the input is one string, containing multiple lines.
Do you want the output to be just one string with multiple lines as well? I'm assuming yes.
either using String and Array operations:
str.lines.reject{|x| x =~ /^>/}.join # this will return a new string, without those ">" lines
or using Regular Expressions:
str.gsub(/^>.+\n*/. '')
Better Solution:
You will need to use non-greedy multi-line matching mode for your Regular Expression:
str.gsub(/^>.*?$\n*/m, '') # by using gsub!() you can modify the string in place
^> matches your ">" character at the start of a line
.*?$ matches any characters after the start character until the end of the line (non-greedy)
\n* matches the newline character itself if any (you want to remove that as well)
the "m" at the end of the regular expressions indicates multi-line matching , which will apply the RegExp for each line in the string.
It should work as you expect:
your_string.lines.to_a.reject{|line| line[0] == '>'}.join

Resources