Find with preg_match all float numbers in text - preg-match

with preg mach i need find all float numbers (x.xx).
preg_match_all('/\d+.\d{1,2}/', $test, $list);
echo '<pre>';
print_r($list);
Now my preg_match find all numbers, but i need only float. How fix this? Thanks

the '.' needs to be escaped..
a '.' means any character.. but you are searching for a literal '.' so you should write
.
preg_match_all('/\d+\.\d{1,2}/', $test, $list);
echo '<pre>';
print_r($list);

Related

How to expend a variable with a quote, on the quote?

Given the following string:
toto="function(param"
I want to get the substring function from the string above, in bash.
I tried the following:
echo "${toto%(}"
Which gives:
function(param
However, with this example:
echo "${toto%param}"
I get:
function(
As expected.
The expansion did not take place when expanding the the character "(".
Why is that ? How can I extract only the beginning (before the "(" of this string ?
To cut ( and anything after it you have match exactly that.
echo "${toto%(*}"

In Perl, best way to insert a char every N chars

I would like to find the best way in Perl to insert a char every N chars in a string.
Suppose I have the following :
my $str = 'ABCDEFGH';
I would like to insert a space every two chars, so that I get:
my $finalstr = 'AB CD EF GH';
The innocent way would be:
my $finalstr;
while ($str =~ s/(..)//) {
$finalstr .= $1.' ';
}
(But the last space does not make me happy.)
Can we do better? Is it possible using a single substitution pattern s///, especially to use that same string $str (and not using $finalstr)?
The next step: do the same but with text before and after patterns to be cut (and to be kept, for sure), say for example '<<' and '>>':
my $str = 'blah <<ABCDEFGH>> blah';
my $finalstr1 = 'blah <<AB CD EF GH>> blah';
my $finalstr2 = 'blah << AB CD EF GH >> blah'; # alternate
Using positive lookahead and lookbehind assertions to insert a space:
my $str = 'ABCDEFGH';
$str =~ s/..\K(?=.)/ /sg;
use Data::Dump;
dd $str;
Outputs:
"AB CD EF GH"
Enhancement for limiting the Translation
If you want to apply this modification to only part of the string, break it into steps:
my $str = 'blah <<ABCDEFGH>> blah';
$str =~ s{<<\K(.*?)(?=>>)}{$1 =~ s/..\K(?=.)/ /sgr}esg;
use Data::Dump;
dd $str;
Outputs:
"blah <<AB CD EF GH>> blah"
The best solution using substitutions would probably be s/\G..\K/ /sg. Why?
The \G anchores at the current “position” of the string. This position is where the last match ended (usually this is set to the beginning of the string. If in doubt, set pos($str) = 0). Because we use the /g modifier, this will be where the previous substitution ended.
The .. matches any two characters. Note that we also use the /s modifier which causes . to really match any character, and not just the [^\n] character class.
The \K treats the previous part of the regex as a look-behind, by not including the previously matched part of the string in the substring that will be substituted. So \G..\K matches the zero length string after two arbitrary characters.
We substitute that zero length string with a single space.
I'd let the regex engine handle the substitution, rather than manually appending $1 . " ". Also, my lookbehind solution avoids the cost of using captures like $1.
You want the //g modifier with its many capabilities. See e.g. here for an introduction to the intricacies of global matching.
Do you mean something like...
$str =~ s/(..)/$1 /sg;
update: For more complex substitutions as the one you are asking in the second part of your question, you can use the e modifier that allows you to evaluate arbitrary perl code:
sub insert_spcs {
my $str = shift;
join ' ', $str =~ /(..?)/sg
}
my $str = 'blah <<ABCDEFGH>> blah';
$str =~ s/<<(.*?)>>/'<< '.insert_spcs($1).' >>'/se;
Personally I'd split the text with m//g and use join:
my $input = "ABCDEFGH";
my $result = join " ", ( $input =~ m/(..)/g );
say "RESULT <$result>";'
Yields
RESULT <AB CD EF GH>
The other answers are better, but just for giggles:
join ' ', grep length, split /(..)/, 'ABCDEFGH';

invalid arithmetic operatior

I am trying to multiply a integer value with a decimal value = 2*1.5. but how it gives me this error,"invalid arithmetic operator".
I researched online and most of the solution provided is just to add that | bc behind the decimal value but however I tried it and it still doesn't work,
results=$((2*"1.5"|bc))
echo $results
try this
results=`bc <<< "scale=2; 2*1.5"`
echo $results
here scale=2 means it will consider 2 decimal places
Please don't forget "`" tilde sign which is important above
You can also try the following:
echo "2*1.5" | bc
$a =2;
$a =(float)$a;
$b=1.5;
echo $a*$b;

atoi() like function in bash?

Imagine that I use a state file to store a number, I read the number like this:
COUNT=$(< /tmp/state_file)
But since the file could be disrupted, $COUNT may not contain a "number", but any characters.
Other than using regex, i.e if [[ $COUNT ~ ^[0-9]+$ ]]; then blabla; fi, is there a "atoi" function that convert it to a number(0 if invalid)?
EDIT
Finally I decided to use something like this:
let a=$(($a+0))
Or
declare -i a; a="abcd123"; echo $a # got 0
Thanks to J20 for the hint.
You don't need an atoi equivalent, Bash variables are untyped. Trying to use variables set to random characters in arithmetic will just silently ignore them. eg
foo1=1
foo2=bar
let foo3=foo1+foo2
echo $foo3
Gives the result 1.
See this reference
echo $COUNT | bc should be able to cast a number, prone to error as per jurgemaister's comments...
echo ${COUNT/[a-Z]*} | bc which is similar to your regex method but not prone to error.
case "$c" in
[0-9])...
You should eat the input string charwise.

Convert (integer,precision) pair to a float in bash/bc

I have two numbers, $value and $precision. I need to make a "floating-point" representation of these numbers (though of course the output will actually be a string, since this is bash).
$precision tells me how many decimal points the number should have.
Example:
$value=123, $precision=2
This should give the output "1.23".
How can I do this elegantly from Bash? I am looking at the "bc" man page but I'm not really seeing any way there. I assume the simplest way is to treat my input value as a string and insert the char '.' in the right position somehow.
In bc:
bc <<EOF
scale = $precision
$value / (10 ^ $precision)
EOF
In sed:
sed -e "s/[0-9]\{$precision\}$/.&/" <<< "$value"
OK, so I found some string manipulation help for Bash ... This does the trick, but it is hardly pretty. Posting it here for posterity.
lastIndex=$((${#value}-1))
dotIndex=$((${#value}-$precision))
decvalue=${value:0:$dotIndex}.${value:$dotIndex:$lastIndex}

Resources