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
I've asked and it was answered but now, after years, it doesn't work.
I've even tried online regex validators. Not sure what is going on.
Version: PHP 7.0.30 on 64Bit OS
The string should only allow digits with commas.
No commas in the beginning or end.
Spaces between commas is ok but I'd rather not allow it.
The following isn't passing
My regex is:
$DateInvoicedIDs = "1031,453,808,387,111,342,962,706,251,442,362,858,950,738,310,288,99,665,1023,30,894,112,132,148,347,895,382,94,766,683,276,1104,658,34,348,235,786,769,2";
$reg = '/[0-9\s]+(,[0-9\s]+)*[0-9]$/';
if ( preg_match($reg, $DateInvoicedIDs) ) {
echo = $DateInvoicedIDs;
} else { echo "false"; }
I'm using preg_match and getting false.
Any idea?
Test your string and pattern # https://regex101.com/r/3TVmOv/1
When that loads, you will see that there is no match highlighted.
Then add a digit to the end of your string and Whalla! This is because (,[0-9\s]+)* is matching the final 2 and [0-9]$ cannot be satisfied because another digit is required.
If I understand your logic/requirements, I think I'd use ~^\d+(?:\s*,\s*\d+)*$~
This improves the validation because it doesn't allow a mixture of digits and spaces between commas like: 2, 3 4 56, 72 I don't think you want spaces in your comma-separated numerical values.
Pattern Demo
Code: (Demo)
$DateInvoicedIDs = "1031,453,808,387,111,342,962,706,251,442,362,858,950,738,310,288,99,665,1023,30,894,112,132,148,347,895,382,94,766,683,276,1104,658,34,348,235,786,769,2";
$reg = '/^\d+(?:\s*,\s*\d+)*$/';
if (preg_match($reg, $DateInvoicedIDs)) {
echo $DateInvoicedIDs;
} else {
echo "false";
}
It is not matching because of the last [0-9] in your regex. The * in (,[0-9\s]+)* is a greedy match which means that it is consuming all commas followed by digits in your string. There is nothing left after to match against the last [0-9].
So you probably want to reduce your regex to '/[0-9\s]+(,[0-9\s]+)*$/.
The last part of your regex [0-9]$ is what's causing it to fail:
[0-9\s]+ is matching the first number only 1031,
(,[0-9\s]+)* is covering everything until ,2 because it's a single number right after a comma which is what it's looking for
Then [0-9]$ is trying to find one more number but it can't
If the last number is a double-digit number, i.e. ,25 instead of 2, then the that second part (,[0-9\s]+)* would be satisfied because it found at least one number and [0-9]$ would match the next number which is 5 (https://regex101.com/r/0XbHsw/1)
Adding ? for that last part would solve the problem: [0-9\s]+(,[0-9\s]+)*[0-9]?$
Is there a way In PHP to just get the first two digits from any given number so for instance:
get 17 from 1700,
14 from 1457,
13 from 130
and if digits are single or double digits leave them as they are.
And at last is there a way to find out if the last two digits of four digit number are zeros so, for instance, distinguish 1700, 1600 etc.
(1) To get the first two digits in php you'll want to use the substr method, as described here:
http://php.net/manual/en/function.substr.php
(2) I'm not clear on what you mean by "leave them as they are" here:
if digits are single or double digits leave them as they are.
(3) For searching for characters in a larger string I would suggest using regular expressions as described here:
http://php.net/manual/en/reference.pcre.pattern.syntax.php
Please note, PCRE regular expressions are a very broad subject, so be sure you really need them. A famous quip about programmers and problems comes to mind.
if (substr($foo, -2) == 00) { // Check if last two digits are zero
echo "double zero!"; // Do something if they are
}
if (strlen($foo) > 2) { // Check if there are more than 2 digits
$foo = substr($foo, 0, 2); // If so only return the first 2 digits
}
echo $foo;
I am using preg_match_all, but I have a problem I am not sure can be solved using this method. The following line is part of what I am retrieving:
XXC033-101-143-147-175-142115-
The sets of numbers (033-101-143, etc) are what I want to refer to. However, the number of sets (always containing three integers) is unknown and can range anywhere from 1 to 10. If I knew there would always only be 2 sets, I would have the following:
if (preg_match_all('#([A-Z]{2}C)([0-9]{3})-([0-9]{3})-([0-9]{6})#', $wwalist, $matches))
...rest of code...
Is there anyway to do this when I have no way of knowing the number of possible sets of 3 integers. They will always be between the #([A-Z]{2}C) and -([0-9]{6}).
Any help would be greatly appreciated! Thanks!
Use
'#([A-Z]{2}C)([0-9]{3}-){1,10}([0-9]{6})#'
{1,10} specifies that the preceding subpattern enclosed in brackets [0-9]{3}- will repeat 1-10 times.
In addition:
If it can repeat 0 or more times for an indefinite maximum number, use *.
If it can repeat 1 or more times for an indefinite maximum number, use +.
Targeting only the 3-digit substrings, individually/optionally capture the groups like this:
Pattern: (Demo)
/[A-Z]{2}C\K(\d{3}-)(\d{3}-)?(\d{3}-)?(\d{3}-)?(\d{3}-)?(\d{3}-)?(\d{3}-)?(\d{3}-)?(\d{3}-)?(\d{3}-)?/
I want to make a regex where I can find the exact number in between a string.
eg. finding the number 2 in 3, 5, 25, 22,2, 15
What I have is /*,2,*/.
But with this regex it matches 22,25 or just anything with a 2 in it. I want it where only match where the number 2 itself is between the commas or without the commas standing alone.
*Update
Both the number(needle) i look for and string(haystack) where i seek it can vary.
Eg if the number i seek is always 2
I want to find them in 2,3,44,23,22,1 or 3,4,22,5,2 or 2 and i should be able to find one match for each of the group of numbers.
You should probably use boundaries (\b) so a leading/trailing comma isn't required.
/\b2\b/
You should do this instead:
,(\d), #for any single digit
,(2), #for 2 in particular
Demo: http://regex101.com/r/vP6jI1