Hello i am passing a bad moment trying to found the correct Regex formula.
$stringSplit = "+foo a -ba24+Sample3";
$vectorsPlus = preg_split('/[+*]/',$stringSplit ,-1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$vectorsMinus = preg_split('/[-*]/',$stringSplit ,-1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
My objetive it's get 2 diferents arrays grouping on symbol like:
$vectorsPlus [0] = '+foo';
$vectorsPlus [1] = '+Sample3';
$vectorsMinus [0] = '-ba24';
I will aprecciate any help how to solves this with the Regex magic.
Instead of using split, you can match the values.
Note that [+*] and [-*] both match a * char and which is not in the example data.
You can match either a + or a - followed by matching the opposite excluding whitespace chars using a negated character class.
$stringSplit = "+foo a -ba24+Sample3";
preg_match_all("/\+[^-+\s]+/", $stringSplit, $matchesPlus);
print_r($matchesPlus[0]);
preg_match_all("/-[^-+\s]+/", $stringSplit, $matchesMinus);
print_r($matchesMinus[0]);
Output
Array
(
[0] => +foo
[1] => +Sample3
)
Array
(
[0] => -ba24
)
See a php demo
Related
Im trying to split between operators and float/int values in a string.
Example:
$input = ">=2.54";
Output should be:
array(0=>">=",1=>"2.54"); .
Operators cases : >,>=,<,<=,=
I tried something like this:
$input = '0.2>';
$exploded = preg_split('/[0-9]+\./', $input);
but its not working.
Here is a working version using preg_split:
$input = ">=2.54";
$parts = preg_split("/(?<=[\d.])(?=[^\d.])|(?<=[^\d.])(?=[\d.])/", $input);
print_r($parts);
This prints:
Array
(
[0] => >=
[1] => 2.54
)
Here is an explanation of the regex used, which says to split when:
(?<=[\d.])(?=[^\d.]) a digit/dot precedes and a non digit/dot follows
| OR
(?<=[^\d.])(?=[\d.]) a non digit/dot precedes and a digit/dot follows
That is, we split at the interface between a number, possibly a decimal, and an arithmetic symbol.
Try :
$input = ">=2.54";
preg_match("/([<>]?=?) ?(\d*(?:\.\d+)?)/",$input,$exploded);
If you want to split between the operators, you might use and alternation to match the variations of the operators, and use \K to reset the starting point of the reported match.
This will give you the position to split on. Then assert using lookarounds that there is a digit on the left or on the right.
\d\K(?=[<>=])|(?:>=?|<=?|=)\K(?=\d)
Explanation
\d\K(?=[<>=]) Match a digit, forget what was matched and assert either <, > or = on the right
| Or
(?:>=?|<=?|=)\K(?=\d) Match an operator, forget what was matched and assert a digit on the right
Regex demo | Php demo
For example
$strings = [
">=2.54",
"=5",
"0.2>"
];
$pattern = '/\d\K(?=[<>=])|(?:>=?|<=?|=)\K(?=\d)/';
foreach ($strings as $string) {
print_r(preg_split($pattern, $string));
}
Output
Array
(
[0] => >=
[1] => 2.54
)
Array
(
[0] => =
[1] => 5
)
Array
(
[0] => 0.2
[1] => >
)
If I have a string like this ,
$my_string="array('red','blue')";
How can I convert this to a real array ?
Example. :
$my_array=array('red','blue');
DO NOT USE EVAL. That is terrible overkill and very probably extremely unsafe.
While this is not the BEST way of doing this (as mentioned in question comments), you can use this below function to do exactly what you need.
How it works:
It uses Regex to find and split the string based on these layouts, the array is split using preg_split which is a regex verson of the more popular explode.
Once split the array will have some blank values so simply use array_filter to remove these blank values.
so:
// Explode string based on regex detection of:
//
// (^\h*[a-z]*\h*\(\h*')
// 1) a-z text with spaces around it and then an opening bracket
// ^ denotes the start of the string
// | denotes a regex OR operator.
// \h denotes whitespace, * denotes zero or more times.
//
// ('\h*,\h*')
// 2) or on '),(' with possible spaces around it
//
// ('\h*\)\h*$)
// 3) or on the final trailing '), again with possible spaces.
// $ denotes the end of the string
// the /i denotes case insensitive.
function makeArray($string){
$stringParts = preg_split("/(^\h*[a-z]*\h*\(\h*')|('\h*,\h*')|('\h*\)\h*$)/i",$string);
// now remove empty array values.
$stringParts = array_filter($stringParts);
return $stringParts;
}
Usage:
//input
$myString = " array('red','blue')";
//action
$array = makeArray($myString);
//output
print_r($array);
Output:
Array (
[1] => red
[2] => blue
)
Example 2:
$myString = " array('red','blue','horses', 'crabs (apples)', '(trapdoor)', '<strong>works</strong>', '436')";
$array = makeArray($myString);
print_r($array);
Output:
Array (
[1] => red
[2] => blue
[3] => horses
[4] => crabs (apples)
[5] => (trapdoor)
[6] => <strong>works</strong>
[7] => 436
)
Obviously the regex may need slight tweaking based on your exact circumstances but this is a very good starting point...
Reference Question/Answers
I have a regex code that splits strings between [.!?], and it works, but I'm trying to add something else to the regex code. I'm trying to make it so that it doesn't match [.] that's between numbers. Is that possible? So, like the example below:
$input = "one.two!three?4.000.";
$inputX = preg_split("~(?>[.!?]+)\K(?!$)~", $input);
print_r($inputX);
Result:
Array ( [0] => one. [1] => two! [2] => three? [3] => 4. [4] => 000. )
Need Result:
Array ( [0] => one. [1] => two! [2] => three? [3] => 4.000. )
You should be able to split on this:
(?<=(?<!\d(?=[.!?]+\d))[.!?])(?![.!?]|$)
https://regex101.com/r/kQ6zO4/1
It uses lookarounds to determine where to split. It looks behind to try to match anything in the set [.!?] one or more times as long as it isn't preceded by and succeeded by a digit.
It also won't return the last empty match by ensuring the last set isn't the end of the string.
UPDATE:
This should be much more efficient actually:
(?!\d+\.\d+).+?[.!?]+\K(?!$)
https://regex101.com/r/eN7rS8/1
Here is another possibility using regex flags:
$input = "one.two!three???4.000.";
$inputX = preg_split("~(\d+\.\d+[.!?]+|.*?[.!?]+)~", $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($inputX);
It includes the delimiter in the split and ignores empty matches. The regex can be simplified to ((?:\d+\.\d+|.*?)[.!?]+), but I think what is in the code sample above is more efficient.
I need help with a regular expression that will find matches in the strings below:
myDOG_test
myCAT_test
Basically, I want to return 'DOG' or 'CAT' from these paths.
Then I have similar strings (all start with 'my') that don't contain the underscore AFTER the value I want, and in that case I just want to return the FULL string -- in a match group.
myCentralReports
myDEMO3
This is the REGEXP that I have so far:
.*?my(.*?)\_.*
This correctly puts CAT & DOG in the matching group, but I'm having problems matching the other 2 strings. Obviously I left the hardcoded underscore in there just to show you what I started with -- but I need to modify this for the other case. Any help is appreciated! Thanks.
Not sure why you need regex:
explode('_', $string);
First element will contain myDOG or myDEMO3. Remove 'my' if needed, it's not clear whether you want 'my' in your second case.
'/\smy(.+?)[_|\s]/'
This will get anything between a whitespace character followed by "my", and the next trailing underscore or whitespace character. try it out.
You could do :
$list = array(' myDOG_test', 'myCAT_test',' myCentralReports', 'myDEMO3');
foreach($list as $elem) {
preg_match("/^\s*my(.+?)(?:_|$)/", $elem, $m);
echo "$elem : matches = ";print_r($m);
}
Output:
myDOG_test : matches = Array
(
[0] => myDOG_
[1] => DOG
)
myCAT_test : matches = Array
(
[0] => myCAT_
[1] => CAT
)
myCentralReports : matches = Array
(
[0] => myCentralReports
[1] => CentralReports
)
myDEMO3 : matches = Array
(
[0] => myDEMO3
[1] => DEMO3
)
Right now i'm trying to get this:
Array
(
[0] => hello
[1] =>
[2] => goodbye
)
Where index 1 is the empty string.
$toBeSplit= 'hello,,goodbye';
$textSplitted = preg_split('/[,]+/', $toBeSplit, -1);
$textSplitted looks like this:
Array
(
[0] => hello
[1] => goodbye
)
I'm using PHP 5.3.2
[,]+ means one or more comma characters while as much as possible is matched. Use just /,/ and it works:
$textSplitted = preg_split('/,/', $toBeSplit, -1);
But you don’t even need regular expression:
$textSplitted = explode(',', $toBeSplit);
How about this:
$textSplitted = preg_split('/,/', $toBeSplit, -1);
Your split regex was grabbing all the commas, not just one.
Your pattern splits the text using a sequence of commas as separator (its syntax also isn't perfect, as you're using a character class for no reason), so two (or two hundred) commas count just as one.
Anyway, since your just using a literal character as separator, use explode():
$str = 'hello,,goodbye';
print_r(explode(',', $str));
output:
Array
(
[0] => hello
[1] =>
[2] => goodbye
)