How to replace a character with null - perl

I have one string
"8.53" I want my resulting string "853"
I have tried
the following code
tr|.||;
but its not replacing its giving 8.53 only .
I have tried another way using
tr|.|NULL|;
but its giving 8N53 can anyone please suggest me how to use tr to replace a character with NULL.
Thanks

You need to specify the d modifier to delete chars with no corresponding char:
tr/.//d;
Or you could use the (slower but more familiar) substitution operator:
s/\.//g;

You don't want tr because that transliterates characters from the 1st list with the corresponding character in the 2nd list (which was N in your example since that was the first character). You'll want the substitution operator.
my $var = "8.53";
$var =~ s/\.//;
print $var;
Add the g flag if there are multiple instances you want to replace (s/\.//g).

Related

How do I replace all occurrences of certain characters with their predecessors?

$s = "bla..bla";
$s =~ s/([^%])\./$1/g;
I think it should replace all occurrences of . that is not after % with the character that is before ..
But $s is then: bla.bla, but
it should be blabla. Where is the problem? I know I can use quantifiers, but I need do it this way.
When a global regular expression is searching a string it will not find overlapping matches.
The first match in your string will be a., which is replaced with a. When the regex engine resumes searching it starts at the next . so it sees .bla as the rest of the string, and your regex requires a character to match before the . so it cannot match again.
Instead, use a negative lookbehind to perform the assertion that the previous character is not %:
$s =~ s/(?<!%)\.//g;
Note that if you use a positive lookbehind like (?<=[^%]), you will not replace the . if it is the first character in the string.
The problem is that even with the /g flag, each substitution starts looking where the previous one left off. You're trying to replace a. with a and then a. with a, but the second replacement doesn't happen because the a has already been "swallowed" by the previous replacement.
One fix is to use a zero-width lookbehind assertion:
$s =~ s/(?<=[^%])\.//g;
which will remove any . that is not the first character in the string, and that is not preceded by %.
But you might actually want this:
$s =~ s/(?<!%)\.//g;
which will remove any . that is not preceded by %, even if it is the first character in the string.
Much simpler than look-behinds is to use:
$s =~ s/([^%])\.+/$1/g;
This replaces any string of one or more dots after a character other than % by nothing.

Why does split not return anything?

I am trying to get that Perl split working for more than 2 hours. I don't see an error. Maybe some other eyes can look at it and see the issue. I am sure its a silly one:
#versionsplit=split('.',"15.0.3");
print $versionsplit[0];
print $versionsplit[1];
print $versionsplit[2];
I just get an empty array. Any idea why?
You need:
#versionsplit=split(/\./,"15.0.3");
The first argument to split is a regular expression, not a string. And . is the regex symbol which means ‘match any character’. So all the characters in your input string were being treated as separators, and split wasn't finding anything between them to return.
the "." represents any character.You need to escape it for split function to recognise as a field separator.
change your line to
#versionsplit=split('\.',"15.0.3");

How to replace a character within a matched pattern using ampersand (&)

When we match a pattern using sed, the matched pattern is stored in the "ampersand" (&) variable. IS there a way to replace a character in this matched pattern using the ampersand itself ?
For example, if & contains the string "apple1", how can I use & to make the string to "apple2" (i.e replace 1 by 2) ?
If I guessed right, what you want to do is to apply a subsitution in a pattern matched. You can't do that using &. You want to do this instead:
echo apple1 apple3 apple1 apple2 botemo1 | sed '/apple./ { s/apple1/apple2/g; }'
This means that you want to execute the command substitution only on the lines that matches the pattern /apple./.
You can also use a capture group. A capture is used to grab a part of the match and save it into an auxiliary variable, that is named numerically in the order that the capture appears.
echo apple1 | sed -e 's/\(a\)\(p*\)\(le\)1/\1\2\32/g'
We used three captures:
The first one, stored in \1, contains an "a"
The second one, stored in \2, contains a sequence of "p"s (in the example it contains "pp")
The third one, stored in \3, contains the sequence "le"
Now we can print the replacement using the matches we captured: \1\2\32. Notice that we are using 3 capture values to generate "apple" and then we append a 2. This wont be interpreted as variable \32 because we can only have a total of 9 captures.
Hope this helps =)
you can first match a pattern and then change the text if matched:
echo "apple1" | sed '/apple/s/1/2/' # gives you "apple2"
this code changes 1 to 2 in all lines containing apple
This might work for you (GNU sed and Bash):
sed 's/apple1/sed "s|1|2|" <<<"&"/e' file

Split by dot using Perl

I use the split function by two ways. First way (string argument to split):
my $string = "chr1.txt";
my #array1 = split(".", $string);
print $array1[0];
I get this error:
Use of uninitialized value in print
When I do split by the second way (regular expression argument to split), I don't get any errors.
my #array1 = split(/\./, $string); print $array1[0];
My first way of splitting is not working only for dot.
What is the reason behind this?
"\." is just ., careful with escape sequences.
If you want a backslash and a dot in a double-quoted string, you need "\\.". Or use single quotes: '\.'
If you just want to parse files and get their suffixes, better use the fileparse() method from File::Basename.
Additional details to the information provided by Mat:
In split "\.", ... the first parameter to split is first interpreted as a double-quoted string before being passed to the regex engine. As Mat said, inside a double-quoted string, a \ is the escape character, meaning "take the next character literally", e.g. for things like putting double quotes inside a double-quoted string: "\""
So your split gets passed "." as the pattern. A single dot means "split on any character". As you know, the split pattern itself is not part of the results. So you have several empty strings as the result.
But why is the first element undefined instead of empty? The answer lies in the documentation for split: if you don't impose a limit on the number of elements returned by split (its third argument) then it will silently remove empty results from the end of the list. As all items are empty the list is empty, hence the first element doesn't exist and is undefined.
You can see the difference with this particular snippet:
my #p1 = split "\.", "thing";
my #p2 = split "\.", "thing", -1;
print scalar(#p1), ' ', scalar(#p2), "\n";
It outputs 0 6.
The "proper" way to deal with this, however, is what #soulSurfer2010 said in his post.

Removing quotes from string

So I thought this would just be a simple issue however I'm getting the incorrect results. Basically I am trying to remove the quotes around a string. For example I have the string "01:00" and I want 01:00, below is the code on how I thought I would be able to do this:
$expected_start_time = $conditions =~ m/(\"[^\"])/;
Every time this runs it returns 1, so I'm guessing that it is just returning true and not actually extracting the string from the quotes. This happen no matter what is in the quotes "02:00", "02:20", "08:00", etc.
All you forgot was parens for the LHS to put the match into list context so it returns the submatch group(s). The normal way to do this is:
($expected_start_time) = $condition =~ /"([^"]*)"/;
It appears that you know that the first and last character are quotes. If that is the case, use
$expected_start_time = substr $conditions, 1, -1;
No need for a regexp.
The brute force way is:
$expected_start_time = $conditions;
$expected_start_time =~ s/"//g;
Note that the original regex:
m/(\"[^\"])/
would capture the opening quote and the following non-quote character. To capture the non-quote characters between double quotes, you'd need some variant on:
m/"([^"]*)"/;
This being Perl (and regexes), TMTOWTDI - There's More Than One Way Do It.
In scalar context a regex returns true if the regex matches the string. You can access the match with $1. See perlre.