Salesforce Apex String replacement funny business - apex-code

Is anyone aware of how to differentiate between the characters '\"' and '"'?
I am trying to pre-process a string and this statement confuses me.
system.assert(' "b" ' == ' "\"" '.replace('\"','b'); //FAILS, returns ' bbb '

In your example, Salesforce is essentially ignoring the backslash as illustrated here:
system.assert('"' == '\"'); // yup
system.assertEquals(1, '\"'.length()); // just one character
system.assertEquals(1, '"'.length()); // just one character--the same one
If your original string has a real backslash character in it, it's the backslash that you need to escape with another backslash like this:
system.assertEquals(1, '\\'.length()); // just one character: \
system.assertEquals(2, '\\"'.length()); // two characters: \"
system.assert(' "b" ' == ' "\\"" '.replace('\\"','b'));

Can you please try this one (replace('\"' instead of replace('\"'):
system.assert(' "b" ' == ' "\"" '.replace('\\"','b');

Related

tr command: strange behavior with | and \

Let's say I have a file test.txt with contents:
+-foo.bar:2.4
| bar.foo:1.1:test
\| hello.goobye:3.3.3
\|+- baz.yeah:4
I want to use the tr command to delete all instances of the following set of characters:
{' ', '+', '-', '|', '\'}
Done some pretty extensive research on this but found no clear/concise answers.
This is the command that works:
input:
cat test.txt | tr -d "[:blank:]|\\\+-"
output:
foo.bar:2.4
bar.foo:1.1:test
hello.goobye:3.3.3
baz.yeah:4
I experimented with many combinations of that set and I found out that the '-' was being treated as a range indicator (like... [a-z]) and therefore must be put at the end. But I have two main questions:
1) Why must the backslash be double escaped in order to be included in the set?
2) Why does putting the '|' at the end of the set string cause the tr program to delete everything in the file except for trailing new line characters?
Like this:
tr -d '\-|\\+[:blank:] ' < file
You have to escape the - because it is used for denoting ranges of characters like:
tr -d '1-5'
and must therefore being escaped if you mean a literal hyphen. You can also put it at the end. (learned that, thanks! :) )
Furthermore the \ must be escaped when you mean a literal \ because it has a special meaning needed for escape sequences.
The remaining characters must not being escaped.
Why must the \ being doubly escaped in your example?
It's because you are using a "" (double quoted) string to quote the char set. A double quoted string will be interpreted by the shell, a \\ in a double quoted string means a literal \. Try:
echo "\+"
echo "\\+"
echo "\\\+"
To avoid to doubly escape the \ you can just use single quotes as in my example above.
Why does putting the '|' at the end of the set string cause the tr program to delete everything in the file except for trailing new line characters?
Following CharlesDuffy's comment having the | at the end means also that you had the unescaped - not at the end, which means it was describing a range of characters where the actual range depends on the position you had it in the set.
another approach is to define the allowed chars
$ tr -cd '[:alnum:]:.\n' <file
foo.bar:2.4
bar.foo:1.1:test
hello.goobye:3.3.3
baz.yeah:4
or, perhaps delete all the prefix non-word chars
$ sed -E 's/\W+//' file

Replacing and substituting characters of the the string in Ruby

What is the best way to replace all characters in the string?
numbers to '.'
'.' to ';'
'-' to '_'
'_' to '-'
I used temporary characters to do it. But it is messed up when the temp character itself appeared in the first string.
I also tried tr method, and it doesn't work for dash and underline.
You have to escape the dash:
print "abc123.-_def.456".tr('-_.0-9', '_\-;.')
// here ___^
Output:
abc...;_-def;...

Ruby - substitute \n if not \\n

I'm trying to do a regex with lookbehind that changes \n to but not if it's a \\n.
My closest attempt has no effect:
text.gsub /(?<!\\)\n/, ''
Unfortunately, no number of backslashes in the lookbehind seem to fix the problem. How can I address this?
You need to double the backslash before the n in the regex, otherwise it's looking for a newline instead of a literal backslash followed by n:
irb(main):001:0> puts "hello\\nthere\\\\n".gsub(/(?<!\\)\\n/, ' ')
hello there\\n
You don't need anything special. "\n" is a single character. It does not include a "\" or "n" character.
text.gsub(/\n/, "")
But instead of that, you should do:
text.gsub("\n", "")
or
text.tr("\n", "")
But I would do:
text.tr($/, "")

How to replace \r in a string in ruby

I have a string that looks like this.
mystring="The Body of a\r\n\t\t\t\tSpider"
I want to replace all the \r, \n, \t etc with a whitespace.
The code I wrote for this is :
mystring.gsub(/\\./, " ")
But this isn't doing anything to the string.
Help.
\r, \n and \t are escape sequences representing carriage return, line feed and tab. Although they are written as two characters, they are interpreted as a single character:
"\r\n\t".codepoints #=> [13, 10, 9]
Because it is such a common requirement, there's a shortcut \s to match all whitespace characters:
mystring.gsub(/\s/, ' ')
#=> "The Body of a Spider"
Or \s+ to match multiple whitespace characters:
mystring.gsub(/\s+/, ' ')
#=> "The Body of a Spider"
/\s/ is equivalent to /[ \t\r\n\f]/
String#tr is designed for stream symbol substitution. It appears to be a bit quickier, than String#gsub:
mystring.tr "\r", ' '
It hasan insplace version also (this will replace all carriage returns, line feed and spaces with space):
mystring.tr! "\s\r\n\t\f", ' '
Stefen's Answer is really very Cool as always comeup with very short and clean solutions. But here what I tried to remove all special characters. [Posted as just optional solution] ;)
> a = "The Body of a\r\n\t\t\t\tSpider"
=> "The Body of a\r\n\t\t\t\tSpider"
> a.gsub(/[^0-9A-Za-z]/, ' ')
=> "The Body of a Spider"
you can use strip , then add a space to your string
mystring.strip . " "
If you literally has \r\n\t in your string:
mystring="The Body of a\r\n\t\t\t\tSpider"
mystring.split(/[\r\t\n]/)

Regex for substituting backslash?

I have this:
a = "whut.\\nErgh"
What I want to achieve is:
"whut.\nErgh" #sub 2 backslashes with 1 backslash
I tried this:
a.gsub(/\\\\/) { '\\' }
but it still returns me two backslashes.
Could someone please explain what went wrong here?
There are not two backslashes in "whut.\\nErgh" but just one.
"\\" is just one backslash char, the first \ is used to escape the backslash in a string.
If you want to convert \\n to a newline char, then use:
"whut.\\nErgh".gsub(/\\n/, "\n")
Try this :
"whut.\\nErgh".gsub(/\\n/, "")

Resources