preg_match_all() to count the 'pattern occurs' thing - php

For example I have the following string 1234567890
pattern is /1|2/
preg_match_all('/1|2/', '1234567890', $out)
gives
[0] ⇒ "1"
[1] ⇒ "2"
But I need to know only the number when the whole pattern occurs (1 time in this case).
Is it possible to find it?
In other words I need to count how many times all pattern occurs
P.S.
for 'closers' and 'downvoters': the question is much wider then just regexpings
Another example:
string sdjka1gsdf1la5wlkasdfcmjsdc8fgvkj
I need to count how many times occurs set of letters a, b and c, followed by digits.
As you can see in this example there'are three occurences - a1, a5 and c8.
So how I can count them?
Example 2:
String where 1 abcd when 1 123456 where 5 when 10 abdc
I need to count how many times whe*+one digit occurs (in this case 3 times)

See preg_match_all manual:
Return Values
Returns the number of full pattern matches (which might be zero), or FALSE if an error occurred.
echo preg_match_all('/[abc]\d+/', 'sdjka1gsdf1la5wlkasdfcmjsdc8fgvkj');
3 demo at eval.in

Related

Regex - multiple matches to accept

I am fairly new to Regex and trying to carry out 3 separate matches on a string, using .php. All 3 must match in order for it to be accepted.
I have a string that will go into a form that specifies the following:
KON-92382
Where KON (Konica) can either be: KON, HEW or CAN
Where '-' is mandatory in this position
Where 5 (strict) digit code must start with 9
So, I need to check the first 3 positions and then TRUE or FALSE
If TRUE, check 4th position and then TRUE or FALSE
Check 5th-9th position that they start with a 9 and then TRUE or FALSE
All 3 checks must result in TRUE, otherwise the check should return FALSE
End users will enter the printer tag into our internal ticketing system and these strings equate to a printer in our assets database.
So far I have tested the following as working, but I need to expand the code so that the '9' can be either 4, 5, 6, 7, 8 or 9 as I am planning to use this number to identify the class of printer (ie - 4 will be A3 Colour MFD)
/(KON|HEW|CAN)(-)(9)[0-9][0-9][0-9][0-9]/
My 'dirty' fix is as follows:
$format = "/(KON-4)|(KON-9)|(HEW-4)|(HEW-9)|(CAN-4)|(CAN-9)(-)[0-9][0-9][0-9][0-9]/";
In this example, i've only specified type 4 or 9 to keep it simple, because the question is more about matching ALL 3 criteria.
Another note, I do not want the 4-9 to be a range (reason being that I want type 5 to fail (ie. KON-51234) as I will be taking all type 5 B/W MFDs out of service pending provider removing from sites and therefore any ticket with this string should fail so that service desk know that this is not an active printer)
Any help is appreciated
You could specify different allowed numbers for every match:
^(?:KON-[46-9]|HEW-[4-9]|CAN-[4-9])\d{4}$
Explanation
^ Start of string
(?: Non capture group for the alternatives
KON-[46-9]|HEW-[4-9]|CAN-[4-9]
) Close non capture group
\d{4} Match 4 digits
$ End of string
See a regex101 demo.
Example for valid matches:
$strings = [
"KON-92382",
"KON-51234",
"HEW-71111",
"CAN-31111",
"KON-912345"
];
$pattern = "/^(?:KON-[46-9]|HEW-[4-9]|CAN-[4-9])\d{4}$/";
print_r(preg_grep($pattern, $strings));
Output
Array
(
[0] => KON-92382
[2] => HEW-71111
)

Regex: match an operation between two factors in mathematical equation

I want to make a regex to match either of multiplication or division operation in mathematical equation which may contain power symbol (^). The match begin between the factor within the most brackets and its nearby variable. I have created my own regex but I faced two main problems:
It doesn't match two factors that not contain * symbol between them (see example 2), I want it match.
It match the operation that only contain - symbol (example 4), I want it doesn't except there is * or / symbol before - symbol (example 3).
Here are my experiments:
EXAMPLE 1
String:
(sdf^sdf*(sdf*(23^3s)))*sdf
Expected result:
(sdf*(23^3s))
My current result:
(sdf*(23^3s))
EXAMPLE 2
String
(232^23)dfdf+dfd(sfsf)
Expected Result
(232^23)dfdf
My current result:
(doesn't match at all)
EXAMPLE 3
String
dfd(sfsf^sdf+323)/-13+sfdfsdf
Expected Result (UPDATED)
dfd(sfsf^sdf+323)
My current result
(sfsf^sdf+323)/-13
EXAMPLE 4
String
(dfd^23sdf)-(234^dfd)
Expected Result
(doesn't match anything)
My current result
(dfd^23sdf)-(234^dfd)
EXAMPLE 5
String
(dfd^23sdf)-(234^dfd)*(x-3)
Expected Result
(234^dfd)*(x-3)
My current result
(dfd^23sdf)-(234^dfd)*(x-3)
Here is my regex:
(\-?)\(?(((\-?)\-?\d*\.?\d*[a-z]*\^?)+)\)?(\*?\/?)((\-?)\(([^\(\)]+)\))(\*?\/?)(\-?)\(?(((\-?)\-?\d*\.?\d*[a-z]*\^?)+)\)|(((\-?)\(([^\(\)]+)\))([\*\/])(\-?)(((?!\+)(\-?)\(?[\-\d\.\w\^\+\-\*\/]*\)?))?)
A suggestion. If you're happy with the regex you've got you can speed it up by making all the groups clusters then running it through regex refactor software here http://www.regexformat.com
Before:
https://regex101.com/r/5Wm1Eb/4
(\-?((\w+\.\^\(.*?\)|([\w\.\^]+))|(\(?\(([^\(\)]+)\)\)?))(((\/)(?!\-))|((\*)(?!\-))|(\/\-)|(\*\-))?\(([^\(\)]+)\))|(\-?\(([^\(\)]+)\)((((\/)(?!\-))|((\*)(?!\-))|(\/\-)|(\*\-))?((\w+\.\^\(.*?\)|([\w\.\^]+))|(\(?\(([^\(\)]+)\)\)?))))
After, twice as fast, half as big:
https://regex101.com/r/TbHlI1/1
\-?(?:(?:\w+\.\^\(.*?\)|[\w\.\^]+|\(?\([^\(\)]+\)\)?)(?:[*/](?:(?!\-)|\-))?\([^\(\)]+\)|\([^\(\)]+\)(?:[*/](?:(?!\-)|\-))?(?:\w+\.\^\(.*?\)|[\w\.\^]+|\(?\([^\(\)]+\)\)?))
After few hours of finding solution, here is what I got:
I write down the regex to match operation like (*), (/), (*-), or (/-).
(((\/)(?!\-))|((\*)(?!\-))|(\/\-)|(\*\-))?
After that, I make a regex to find the factor within the most brackets and its closest back variable which match the condition.
(((\w+\^\(.*?\)|([\w\^]+))|(\(?\(([^\(\)]+)\)\)?))(((\/)(?!\-))|((\*)(?!\-))|(\/\-)|(\*\-))?\(([^\(\)]+)\))
If it doesn't match, then try again to find the factor within the most brackets and its closest front variable which match the condition.
(\(([^\(\)]+)\)((((\/)(?!\-))|((\*)(?!\-))|(\/\-)|(\*\-))?((\w+\^\(.*?\)|([\w\^]+))|(\(?\(([^\(\)]+)\)\)?))))
Then, combine those two regexs above using OR (|) quantifier to get the desired result.
DEMO
UPDATED
I modified some parts, so it can match negative factor and decimal (marked with '.' symbol).
DEMO

how to find a number phrase in php which at least have 2 digit

i try to use a rss code , i want get codes of rss and find a number phrase in it, here is the markup :
bokk 1 is there 23453
shot 3 ao adfsdf 348943
aadd 4 asdis 4321334
adfie 9 aioe 938
how define a pattern to push numbers which have a leat to digit in an array in php language ?
i think eregi() functions can be useable, but don't know how use it,
for more explain , first line has a 5 digit number(23453) and second line has a 6 digit number(348943) and so on... how to save these number in an array where at leat has 2 digit and the numbers of digit is unlimited,
You can use regex:
preg_match_all("/([0-9]{2,})/", $string, $match);

How to match those numbers?

I have an array of numbers, for example:
10001234
10002345
Now I have a number, which should be matched against all of those numbers inside the array. The number could either be 10001234 (which would be easy to match), but it could also be 100001234 (4 zeros instead of 3) or 101234 (one zero instead of 3) for example. Any combination could be possible. The only fixed part is the 1234 at the end.
I cant get the last 4 chars, because it can also be 3 or 5 or 6 ..., like 1000123456.
Whats a good way to match that? Maybe its easy and I dont see the wood for the trees :D.
Thanks!
if always the first number is one you can use this
$Num=1000436346;
echo(int)ltrim($Num."","1");
output:
436346
$number % 10000
Will return the remainder of dividing a number by 10000. Meaning, the last four digits.
The question doesn't make the criteria for the match very clear. However, I'll give it a go.
First, my assumptions:
The number always starts with a 1 followed by an unknown number of 0s.
After that, we have a sequence of digits which could be anything (but presumably not starting with zero?), which you want to extract from the string?
Given the above, we can formulate an expression fairly easily:
$input='10002345';
if(preg_match('/10+(\d+)/',$input,$matches)) {
$output = $matches[1];
}
$output now contains the second part of the number -- ie 2345.
If you need to match more than just a leading 1, you can replace that in the expression with \d to match any digit. And add a plus sign after it to allow more than one digit here (although we're still relying on there being at least one zero between the first part of the number and the second).
$input='10002345';
if(preg_match('/\d+0+(\d+)/',$input,$matches)) {
$output = $matches[1];
}

Find common chars in array of strings, in the right order

I spent days working on a function to get common chars in an array of strings, in the right order, to create a wildcard.
Here is an example to explain my problem. I made about 3 functions, but I always have a bug when the absolute position of each letter is different.
Let's assume "+" is the "wildcard char":
Array(
0 => '48ca135e0$5',
1 => 'b8ca136a0$5',
2 => 'c48ca13730$5',
3 => '48ca137a0$5');
Should return :
$wildcard='+8ca13+0$5';
In this example, the tricky thing is that $array[2] as 1 char more than others.
Other example :
Array(
0 => "case1b25.occHH&FmM",
1 => "case11b25.occHH&FmM",
2 => "case12b25.occHH&FmM",
3 => "case20b25.occHH&FmM1");
Should return :
$wildcard='case+b25.occHH&FmM+';
In this example, the tricky parts are :
- Repeating chars, such as 1 -> 11 in the "to delete" part, and c -> cc in the common part
- The "2" char in $array[2] & [3] in the "to delete" part is not in the same position
- The "1" char at the end of the last string
I really need help because I can't find a solution to this function and it is a main part of my application.
Thanks in advance, don't hesitate to ask questions, I will answer as fast as possible.
Mykeul
Seems you want to create something like regular expression out of set of example strings.
This might be quite tricki in general. Found this link, not sure if it's relevant:
http://scholar.google.com/scholar?hl=en&rlz=1B3GGGL_enEE351EE351&q=%22regular%20expression%20by%20example%22&oq=&um=1&ie=UTF-8&sa=N&tab=ws
On the other hand, if you need only one specific wildcard meaning "0 or more characters", then it should be much easier. Levenshtein distance algorithm computes similarity between 2 strings. Normally only result is needed, but in your case the places of differences are important. You also need to adapt this for N strings.
So I recommend to study this algorithm and hopefully you'll get some ideas how to solve your problem (at least you'll get some practice with text algorithms and dynamic programming).
Heres algorithm in PHP:
_http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#PHP
You might want also to search for PHP implementations of "diff".
http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/
Main code:
Step 1: Sort strings by length, shortest to longest, into array[]
Step 2: Compare string in array[0] and array[1] to get $temp_wildcard
Step 3: Compare string in array[2] with $temp_wildcard to create new $temp_wildcard
Step 4: Continue comparing each string with $temp_wildcard - the last $wildcard is your $temp_wildcard
OK, so now we're down to the problem of how to compare two strings to return your wildcard string.
Subroutine code:
Compare strings character-by-character, substituting wildcards into your return value when the comparison doesn't match.
To handle the problem of different lengths, run this comparison an extra time for each character that the second string is longer with an offset. (Compare string1[x] to string2[x+offset].) For each returned string, count the number of wildcard characters. The subroutine should return the answer with the fewest number of wildcard characters.
Good luck!

Categories