pre_replace $23,852.50, remove '$' and ',' - preg-replace

I have variable which stores price
$price = $23,852.50
I want to remove $ sign and ',' from my variable, so I can use this number for multiplication, addition and subtraction.
I am trying this
echo preg_replace("(\\$)", "", '$23,852.50');
Which is removing the $ sign but I don't know how to add ',' with it too.

For this i would just use str_replace() just use an array for the first variable.
echo str_replace(array("$", ","), "", $price);

As Michael Smith said, you'd better use str_replace, but if you really want to use preg_replace, do:
preg_replace("/[$,]+/", "", '$23,852.50');
Where [$,] is a character class that matches $ or ,.

With strtr:
$price = strtr($price, array('$'=>'', ','=>''));
The advantage of strtr is that the string is parsed only once whatever the number of replace pairs in the array.

Related

For what input and arguments will perl split give the result (""), if ever?

To me, it looks like perl split can never give the result (""), i.e. a single-element list whose single element is the empty string. No matter what -- any input, any arguments to split. Can anyone show otherwise? And if not, is this a feature or a bug?
I wanted split to be able to for consistency, but alas:
Note that splitting an EXPR that evaluates to the empty string always
produces zero fields, regardless of the LIMIT specified.
http://perldoc.perl.org/functions/split.html
E.g.:
$ echo ""|perl -ne 'chomp;print 0+split/x/,$_,-1'
0
$ echo "x"|perl -ne 'chomp;print 0+split/x/,$_,-1'
2
$ echo "xx"|perl -ne 'chomp;print 0+split/x/,$_,-1'
3
$ echo "xxx"|perl -ne 'chomp;print 0+split/x/,$_,-1'
4
And if not, is this a feature or a bug?
Not returning an empty string is not a bug. As per the documentation,
Note that splitting an EXPR that evaluates to the empty string always produces zero fields, regardless of the LIMIT specified.
Can anyone show otherwise?
It's highly unlikely that anyone will be able to find an input for which split return an empty string when it's documented to never return an empty string.
It sounds like you want a list of one item when the input is an empty string, so
length($_) ? split(..., $_, -1) : ""
This is a tentative answer to my own question, pending any further information/correction that may come from others:
There are no inputs and arguments to perl split for which the result will ever be a single-element list containing the empty string.
In order to get a result consistent with the promises 1) "size of result will always be one more than the number of separators (regexp matches)" and 2) "if there are no separators, the result will always be a single-element list whose element is the whole original string", what would normally be a clean function call expression
split /.../
instead needs to be wrapped as follows, including an additional auxiliary array:
#s = split /.../, $_, -1 or push #s, "";
and then #s used where the split /.../ normally would have been.
E.g.:
$ echo ""|perl -ne 'chomp;#s=split/x/,$_,-1 or push #s,"";print 0+#s'
1
$ echo "x"|perl -ne 'chomp;#s=split/x/,$_,-1 or push #s,"";print 0+#s'
2
$ echo "xx"|perl -ne 'chomp;#s=split/x/,$_,-1 or push #s,"";print 0+#s'
3
$ echo "xxx"|perl -ne 'chomp;#s=split/x/,$_,-1 or push #s,"";print 0+#s'
4
Or, alternatively, any code using bare split /.../ and relying on either of the above "promises" needs to be put inside a guard if (length) {...} and the case of length==0 handled in separate code.

what's the proper syntax to insert a multi-line substitution string and apply it toward a single array value?

Here's the scenario -- One step of the process involves fixing city names when the data is obviously misspelled, along with some basic conversions like "MTN" to "Mountain" and so forth. I've built a variable containing several substitution strings, and I'm trying to apply that set of subs on one of the input fields later down the line.
my $citysub = <<'EOF';
s/DEQUEEN/DE QUEEN/;
s/ELDORADO/EL DORADO/;
... # there are about 100 such substitution strings
EOF
...
while ($line <INFILE>)
{
...
#field = split(/","/,$line); # it's a comma-delimited file with quoted strings; this is spltting exactly like I intend; at the end, I'll piece it back together properly
...
# the 9th field and 12th field are city names, i.e., $field[8] and $field[12]
$field[8] =~ $citysub; # this is what I'm wanting to do, but it doesn't work!
# since that doesn't work, I'm using the following, but it's much slower, obviiously
$field[8] = `echo $field[8]|sed -e "$citysub"`; # external calls to system commands
So, what's the proper syntax to insert a multi-line substitution string and apply it toward a single array value?
my %citysub = ( "DEQUEEN" => "DE QUEEN", "ELDORADO" => "EL DORADO" );
for my $find ( keys %citysub ) {
my $replace = $citysub{ $find };
$field[8] =~ s/$find/$replace/g;
}
Explanation: Create a hash of "thing to match" => "thing to replace with". then loop over that hash and run s/// with the thing to match and the thing to replace with.

How to replace a $ in a string in perl script

I have a string,
$str = abc#$and#def
I tried to replace '$' with it's hex value using ,
$str=~s/$/%26/g
But the output is abc#.
This might be because '$'is considered as the end of the line or string.
Please let me know
Your problem is nothing to do with your substitution; when you are assigning to the string in the first place:
$str = "abc#$and#def";
$and and #def are treated as variables to interpolate.
You need to escape the sigils or use single quotes (which don't interpolate variables):
$str = 'abc#$and#def';
# or
$str = "abc#\$and\#def";
And you really really need to enable warnings, which would have told you your assignment was the problem.
You need to escape the $ with a \
$str =~ s/\$/%26/g
Try escaping the $ with a \:
$str =~ s/\$/%26/g;
Ron

What does the Perl split function return when there is no value between tokens?

I'm trying to split a string using the split function but there isn't always a value between tokens.
Ex: ABC,123,,,,,,XYZ
I don't want to skip the multiple tokens though. These values are in specific positions in the string. However, when I do a split, and then try to step through my resulting array, I get "Use of uninitialized value" warnings.
I've tried comparing the value using $splitvalues[x] eq "" and I've tried using defined($splitvalues[x]) , but I can't for the life of me figure out how to identify what the split function is putting in to my array when there is no value between tokens.
Here's the snippet of my code (now with more crunchy goodness):
my #matrixDetail = ();
#some other processing happens here that is based on matching data from the
##oldDetail array with the first field of the #matrixLine array. If it does
#match, then I do the split
if($IHaveAMatch)
{
#matrixDetail = split(',', $matrixLine[1]);
}
else
{
#matrixDetail = ('','','','','','','');
}
my $newDetailString =
(($matrixDetail[0] eq '') ? $oldDetail[0] : $matrixDetail[0])
. (($matrixDetail[1] eq '') ? $oldDetail[1] : $matrixDetail[1])
.
.
.
. (($matrixDetail[6] eq '') ? $oldDetail[6] : $matrixDetail[6]);
because this is just snippets, I've left some of the other logic out, but the if statement is inside a sub that technically returns the #matrixDetail array back. If I don't find a match in my matrix and set the array equal to the array of empty strings manually, then I get no warnings. It's only when the split populates the #matrixDetail.
Also, I should mention, I've been writing code for nearly 15 years, but only very recently have I needed to work with Perl. The logic in my script is sound (or at least, it works), I'm just being anal about cleaning up my warnings and trying to figure out this little nuance.
#!perl
use warnings;
use strict;
use Data::Dumper;
my $str = "ABC,123,,,,,,XYZ";
my #elems = split ',', $str;
print Dumper \#elems;
This gives:
$VAR1 = [
'ABC',
'123',
'',
'',
'',
'',
'',
'XYZ'
];
It puts in an empty string.
Edit: Note that the documentation for split() states that "by default, empty leading fields are preserved, and empty trailing ones are deleted." Thus, if your string is ABC,123,,,,,,XYZ,,,, then your returned list will be the same as the above example, but if your string is ,,,,ABC,123, then you will have a list with three empty strings in elements 0, 1, and 2 (in addition to 'ABC' and '123').
Edit 2: Try dumping out the #matrixDetail and #oldDetail arrays. It's likely that one of those isn't the length that you think it is. You might also consider checking the number of elements in those two lists before trying to use them to make sure you have as many elements as you're expecting.
I suggest to use Text::CSV from CPAN. It is a ready made solution which already covers all the weird edge cases of parsing CSV formatted files.
delims with nothing between them give empty strings when split. Empty strings evaluate as false in boolean context.
If you know that your "details" input will never contain "0" (or other scalar that evaluates to false), this should work:
my #matrixDetail = split(',', $matrixLine[1]);
die if #matrixDetail > #oldDetail;
my $newDetailString = "";
for my $i (0..$#oldDetail) {
$newDetailString .= $matrixDetail[$i] || $oldDetail[$i]; # thanks canSpice
}
say $newDetailString;
(there are probably other scalars besides empty string and zero that evaluate to false but I couldn't name them off the top of my head.)
TMTOWTDI:
$matrixDetail[$_] ||= $oldDetail[$_] for 0..$#oldDetail;
my $newDetailString = join("", #matrixDetail);
edit: for loops now go from 0 to $#oldDetail instead of $#matrixDetail since trailing ",,," are not returned by split.
edit2: if you can't be sure that real input won't evaluate as false, you could always just test the length of your split elements. This is safer, definitely, though perhaps less elegant ^_^
Empty fields in the middle will be ''. Empty fields on the end will be omitted, unless you specify a third parameter to split large enough (or -1 for all).

How do I place a colon into a string two characters from the end using Perl?

I'm trying to find a way to place a colon ( : ) into a string, two characters from the end of the string.
Examples of $meetdays:
1200 => 12:00900 => 9:001340 =>13:40
Not sure if this should be a regular expression or just another function that I'm not aware of.
Can also use substr() as well.....
my $string = "1200";
substr $string, -2, 0, ':';
# $string => '12:00';
s/(?=..$)/:/
Don't use roe's suggestion of $&. perldoc perlvar:
The use of this variable anywhere in a program imposes a considerable performance penalty on all regular expression matches. See "BUGS".
You could try this:
s/..$/:$&/
it matches two-characters at the end of the string, and replaces it with a colon, and the matched string (i.e. the two characters).
EDIT
Fixed sed-backref to the perl equivalent.
roe's answer "works" , but its rather inobvious regex.
I would more go for
s/(^.*)(..$)/$1:$2/
Because I just love backrefs.
Its overkill for what you're doing, but to me its more semantically expressive.
The Perl equivalent of sed's & is $&, so it should be:
$s = s /..$/:$&/s;