Find a Word after a particular word - php

I am not so expert in the regular expression. I have created a function to find out a particular word after a first match word from an array. the code is
$searchkey1 = array('NUMBER', 'REF', 'TRANSACTION NUMBER');
$searchkey2 = array('CURRENT BALANCE RS.', 'NEW BALANCE IS');
$smsdata = "TRANSACTION NUMBER NER13082010132400255 TO RECHARGE 198 INR TO 9999999999 IS SUCCESSFUL. YOUR NEW BALANCE IS 8183.79 INR.";
function get_details($searchkey, $smsdata)
{
foreach ($searchkey as $key) {
$result = preg_match_all("/(?<=(" . $key . "))(\s\w*)/", $smsdata, $networkID);
$myanswer = #$networkID[0][0];
}
return $myanswer;
}
echo get_details($searchkey1, $smsdata);
echo "<BR>";
echo get_details($searchkey2, $smsdata);
I am using this function to find out other words also. and it is working find for any other words except the decimal value.
Here in my example code the return value is 11192 but i would like to get with decimal as 11192.75
Please rectify my error.
$result=preg_match_all("/(?<=(".$key."))(\s\w*)/",$smsdata,$networkID);
give the result NER13082010132400255 and 8183 //here the demical is ignore.
$result=preg_match_all("/(?<=(".$key."))\s*(\d*\.?\d*)/",$smsdata,$networkID);
give the result "blank" and 8183.79 // here the first results is blank
My desire result is NER13082010132400255 and 8183.79

i don't believe \w covers period. use a mixture of \d and \.
$result=preg_match_all("/(?<=(".$key."))(\s[\d\.]+)/",$smsdata,$networkID);

The OP's regexp captures the leading space too.
#DevZer0's regexp captures the trailing dot too.
This gives the balance only:
$result=preg_match_all("/(?<=(".$key."))\s*(\d*\.?\d*)/",$smsdata,$networkID);

Related

PHP search in a variable text and save it

I have this autogenerated variable:
$var = "WXYZ 300700Z 32011KT 9999 FEW035 SCT200 24/16 Q1007 NOSIG";
How can I search and save "9999" in this var? I cant use substr cause $var's value is always changing and it is always in another "place" in the variable. It is always 4 numbers.
You can match 4 numbers wrapped by word boundaries or space characters, depending on what you need with regular expression (regex/regexp).
if( preg_match('/\b([0-9]{4})\b/', $var, $matches) > 0 ) {
// $matches[1] contains the number
}
Note, however, that the word boundary match will also match on non-letter characters (symbols like dollar sign ($), hyphen (-), period (.), comma (,), etc.). So a string of "XYZ ABC 9843-AB YZV" would match the "9843". If you want to just match based on numbers surrounded by white space (spaces, tabs, etc) you can use:
if( preg_match('/(?:^|\s)([0-9]{4})(?:\s|$)/', $var, $matches) > 0 ) {
// $matches[1] contains the number
}
Using explode is the way to go, we need to turn the string into an array, our variables are separated by white space, so we get a variable every time we face a white space " ", i made another example to understand how explode works.
<?php
$var = "WXYZ 300700Z 32011KT 9999 FEW035 SCT200 24/16 Q1007 NOSIG";
print_r (explode(" ",$var)); //Display the full array.
$var_search = explode(" ",$var);
echo $var_search[3];//To echo the 9999 (4th position).
?>
<br>
<?php
$var = "WXYZ+300700Z+32011KT+9999+FEW035+SCT200+24/16+Q1007+NOSIG";
print_r (explode("+",$var)); //Display the full array.
$var_search = explode("+",$var);
echo $var_search[3];//To echo the 9999 (4th position).
?>
I hop this is what you're looking for
Is this viable?
$var = "WXYZ 300700Z 32011KT 9999 FEW035 SCT200 24/16 Q1007 NOSIG";
if (strpos($var, '9999') == true {
// blah blah
}
else{
echo 'Value not found'
}
Personally haven't tested this yet, but I think you're looking for something along these lines...
Hello I would use a preg_match regex using this regular expression : \d{4}
here is the solution
var str1 = "WXYZ 300700Z 32011KT 9999 FEW035 SCT200 24/16 Q1007 NOSIG";
var str2 = "9999";
if(str1.indexOf(str2) != -1){
console.log(str2 + " found");
}

php replace with regex and remove specified pattern with regex

|affffc100|Hitem:bb:101:1:1:1:1:48:-30:47:18:5:2:6:6:0:0:0:0:0:0:0:0|h[Subject Name]|h|r
my usual printed out variable is ^
|cffffc700|Hitem:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x|h[SUBJECT_NAME]|h|r
my pattern is ^
ALL X's can be a-Z, 0-9
in one column I have many variables like that (up to 8).
and all variables are mixed with strings like that:
|affffc100|Hitem:bb:101:1:1:1:1:48:-30:47:18:5:2:6:6:0:0:0:0:0:0:0:0|h[Gold]|h|r NEW SOLD |affffc451|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Copper]|h|r maximum price 15k|affffx312|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Silver]|h|r
In one variable I want to clean all these unnecessary patterns and leave only subject name in brackets. []
So;
|cffffc700|Hitem:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x|h[SUBJECT NAME]|h|r
needs to leave only SUBJECT_NAME in my variable.
just to remind, I have always more than one from these pattern in my every variable... (up to 8)
I've searched it everywhere but couldn't find any reasonable answers NOR good patterns. Tried to make it myself but I guess I need to take all these patterns and make it array and clean it and only leave these subject names but I don't know exactly how to do it.
how do I convert this to :
|affffc100|Hitem:bb:101:1:1:1:1:48:-30:47:18:5:2:6:6:0:0:0:0:0:0:0:0|h[Gold]|h|r NEW SOLD |affffc451|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Copper]|h|r maximum price 15k|affffx312|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Silver]|h|r
this:
Gold NEW SOLD Copper maxiumum price 15k Silver
what should I use, preg_replace?
one more thing left, when I have a string without my special pattern, I get empty result from the function eg:
$str = "15KKK sold, 20KK updated";
expected result:
"15KKK sold, 20KK updated" // same without any pattern
but ^ that one returns EMPTY result..
another string:
$str = "|affffc100|Hitem:bb:101:1:1:1:1:48:-30:47:18:5:2:6:6:0:0:0:0:0:0:0:0|h[Uranium]|h|r 155kk |affffc451|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Metal]|h|r is sold";
expected result:
"Uranium 155kk Metal is sold"
if I use that function with non-pattern string it returns empty result that's my problem now
thank you very much
I'd do:
$str = '|affffc100|Hitem:bb:101:1:1:1:1:48:-30:47:18:5:2:6:6:0:0:0:0:0:0:0:0|h[Gold]|h|r NEW SOLD |affffc451|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Copper]|h|r maximum price 15k|affffx312|Hitem:bb:101:1:1:1:1:25:-33:12:42:5a:2f:6w:6:0:0:0:0f:0:0a:0b:0|h[Silver]|h|r';
preg_match_all('/h(\[.+?\])\|h\|r([^|]*)/', $str, $m);
for($i=0; $i<count($m[0]); $i++) {
$res .= $m[1][$i] . ' ' . $m[2][$i] . ' ';
}
echo $res,"\n";
Output:
[Gold] NEW SOLD [Copper] maximum price 15k [Silver]
If you want to keep the strings that don't match, test the result of preg_match:
if (preg_match_all('/h(\[.+?\])\|h\|r([^|]*)/', $str, $m)) {
for($i=0; $i<count($m[0]); $i++) {
$res .= $m[1][$i] . ' ' . $m[2][$i] . ' ';
}
} else {
$res = $str;
}
echo $res,"\n";
try this regex:
\|\w{9}\|Hitem(?::-?\w+)+\|h\[(?<SUBJECTNAME>\w+)\]\|h\|r
it will capture each variable sequence, as well as the relevant element name in the named group.
see the demo here

Get text contained within the parentheses at the end of string

Say I have this user list:
Michael (43)
Peter (1) (143)
Peter (2) (144)
Daniel (12)
The number in the furthest right set of parentheses is the user number.
I want to loop each user and get the highest user number in the list, which in this case would be 144.
How do I do this? I'm sure it can be done with some kind of regexp, but I have no idea how. My loop is simple:
$currentUserNO = 0;
foreach ($users as $user) {
$userNO = $user->NameUserNo; // NameUserNo is the string to be stripped! ex: "Peter (2) (144)" => 144
if ($userNO > $currentUserNO) {
$currentUserNO = $userNO;
}
}
echo "The next user will be added with the user number: " . $currentUserNO + 1;
You could use a regex like:
/\((\d+)\)$/
^ glued to the end of the string
^^ closing parentheses
^^^ the number you want to capture
^^ opening parentheses
to capture the number in the last set of parentheses / at the end of the string.
But you could also use some basic array and string functions:
$parts = explode('(', trim($user->NameUserNo, ' )'));
$number = end($parts);
which breaks down to:
trim the closing parentheses and spaces from the end (strictly speaking from the beginning and end, you could also use rtrim());
explode on the opening parentheses;
get the last element of the resulting array.
If you are not confortable with regular expression you should not use them (and start to seriously learn them* as they are very powerful but cryptic).
In the mean time you don't have to use regex to solve your problem, just use (assuming that the NameUserNo contains just a line of the list) :
$userNO = substr(end(explode('(',$user->NameUserNo;)),0,-1);
It should be easier to understand.
* Is there a good, online, interactive regex tutorial?
I think the regular expression you are looking for is:
.+\((\d+)\)$
Which should select all characters until it reaches the last number wrapped in parenthesis.
The PHP code you can use to extract just the number is then:
$userNO = preg_replace('/.+\((\d+)\)$/', '$1', $user);
I haven't tested this, but it should set $userNO to 43 for the user Michael and 143 for the user Peter and so on.
I guess this is basically what you are looking for:
<?php
$list = array();
foreach $users as $user) {
preg_match('/$([a-zA-Z]+).*\([1-9]+\)$/', , $tokens);
$list[$tokens[2]] = $tokens[1];
}
ksort($list);
$highest = last(array_keys($list));
echo "The next user will be added with the user number: " . $highest++;
This is pretty easy to do with a regex.
foreach ($users as $user) {
# search for any characters then a number in brackets
# the match will be in $matches[1]
preg_match("/.+\((\d+)\)/", $user->NameUserNo, $matches);
$userNO = $matches[1];
if ($userNO > $currentUserNO) {
$currentUserNO = $userNO;
}
}
Because regexs use greedy matching, the .+, which means search for one or more characters, will grab up as much of the input string as it can before it reaches the number in brackets.
I'm fairly new to PHP, but couldn't you do it with:
$exploded = explode(" ", $user->NameUserNumber);
$userNo = substr(end($exploded), 1,-1);

Regular expression for numeric values and a single decimal place in PHP

Attempting to parse only numeric values and a single decimal place with the following regular expression but characters are also being parsed. Any ideas?
<?php
function get_rate1(SimpleXMLElement $xml) {
$exchange['rate'] = $xml->channel->item[15]->description;
$rate = preg_replace("/^([0-9]*|\d*\.\d{1}?\d*)$/", '', $exchange['rate']);
echo $rate . '<br />';
return $rate;
}
?>
Expected results:
11.20409
Actual results:
1 British Pound Sterling = 1.20409 Euro
Desired Results:
1.20409
Furthermore, any ideas how to remove the first numeric value as the number 1 displayed prior to British Pound Sterling would make the value incorrect.
Thanks in advance
if (preg_match("([0-9]+\.[0-9]{1}", $string, $matches)) {
echo $matches[1];
} else {
throw new Exception("GIVE ME NUMBERS, lol");
}
On "This is a text 1.234 with a number" should give "1.2"
Does not match numbers like .123
Actually, the regex should be:
'/\d*\.\d/'
this will match any number of digits (0 or more) before the decimal, and exactly one past it. There are some other problems with Frits van Campen's regex, particularly an unclosed paren.

Using regex to fix phone numbers in a CSV with PHP

My new phone does not recognize a phone number unless its area code matches the incoming call. Since I live in Idaho where an area code is not needed for in-state calls, many of my contacts were saved without an area code. Since I have thousands of contacts stored in my phone, it would not be practical to manually update them. I decided to write the following PHP script to handle the problem. It seems to work well, except that I'm finding duplicate area codes at the beginning of random contacts.
<?php
//the script can take a while to complete
set_time_limit(200);
function validate_area_code($number) {
//digits are taken one by one out of $number, and insert in to $numString
$numString = "";
for ($i = 0; $i < strlen($number); $i++) {
$curr = substr($number,$i,1);
//only copy from $number to $numString when the character is numeric
if (is_numeric($curr)) {
$numString = $numString . $curr;
}
}
//add area code "208" to the beginning of any phone number of length 7
if (strlen($numString) == 7) {
return "208" . $numString;
//remove country code (none of the contacts are outside the U.S.)
} else if (strlen($numString) == 11) {
return preg_replace("/^1/","",$numString);
} else {
return $numString;
}
}
//matches any phone number in the csv
$pattern = "/((1? ?\(?[2-9]\d\d\)? *)? ?\d\d\d-?\d\d\d\d)/";
$csv = file_get_contents("contacts2.CSV");
preg_match_all($pattern,$csv,$matches);
foreach ($matches[0] as $key1 => $value) {
/*create a pattern that matches the specific phone number by adding slashes before possible special characters*/
$pattern = preg_replace("/\(|\)|\-/","\\\\$0",$value);
//create the replacement phone number
$replacement = validate_area_code($value);
//add delimeters
$pattern = "/" . $pattern . "/";
$csv = preg_replace($pattern,$replacement,$csv);
}
echo $csv;
?>
Is there a better approach to modifying the CSV? Also, is there a way to minimize the number of passes over the CSV? In the script above, preg_replace is called thousands of times on a very large String.
If I understand you correctly, you just need to prepend the area code to any 7-digit phone number anywhere in this file, right? I have no idea what kind of system you're on, but if you have some decent tools, here are a couple options. And of course, the approaches they take can presumably be implemented in PHP; that's just not one of my languages.
So, how about a sed one-liner? Just look for 7-digit phone numbers, bounded by either beginning of line or comma on the left, and comma or end of line on the right.
sed -r 's/(^|,)([0-9]{3}-[0-9]{4})(,|$)/\1208-\2\3/g' contacts.csv
Or if you want to only apply it to certain fields, perl (or awk) would be easier. Suppose it's the second field:
perl -F, -ane '$"=","; $F[1]=~s/^[0-9]{3}-[0-9]{4}$/208-$&/; print "#F";' contacts.csv
The -F, indicates the field separator, the $" is the output field separator (yes, it gets assigned once per loop, oh well), the arrays are zero-indexed so second field is $F[1], there's a run-of-the-mill substitution, and you print the results.
Ah programs... sometimes a 10-min hack is better.
If it were me... I'd import the CSV into Excel, sort it by something - maybe the length of the phone number or something. Make a new col for the fixed phone number. When you have a group of similarly-fouled numbers, make a formula to fix. Same for the next group. Should be pretty quick, no? Then export to .csv again, omitting the bad col.
A little more digging on my own revealed the issues with the regex in my question. The problem is with duplicate contacts in the csv.
Example:
(208) 555-5555, 555-5555
After the first pass becomes:
2085555555, 208555555
and After the second pass becomes
2082085555555, 2082085555555
I worked around this by changing the replacement regex to:
//add escapes for special characters
$pattern = preg_replace("/\(|\)|\-|\./","\\\\$0",$value);
//add delimiters, and optional area code
$pattern = "/(\(?[0-9]{3}\)?)? ?" . $pattern . "/";

Categories