I am trying to find all the numbers after a capital letter. See the example below:
E1S1 should give me an array containing: [1 , 1]
S123455D1223 should give me an array containing: [123455 , 1223]
i tried the following but didnt get any matches on any of the examples shown above :(
$loc = "E123S5";
$locs = array();
preg_match('/\[A-Z]([0-9])/', $loc, $locs);
any help is greatly appreciated i am a newbie to regex.
Your regex \[A-Z]([0-9]) matches a literal [ (as it is escaped), then A-Z] as a char sequence (since the character class [...] is broken) and then matches and captures a single ASCII digit (with ([0-9])). Also, you are using a preg_match function that only returns 1 match, not all matches.
You might fix it with
preg_match_all('/[A-Z]([0-9]+)/', $loc, $locs);
The $locs\[1\] will contain the values you need.
Alternatively, you may use a [A-Z]\K[0-9]+ regex:
$loc = "E123S5";
$locs = array();
preg_match_all('/[A-Z]\K[0-9]+/', $loc, $locs);
print_r($locs[0]);
Result:
Array
(
[0] => 123
[1] => 5
)
See the online PHP demo.
Pattern details
[A-Z] - an upper case ASCII letter (to support all Unicode ones, use \p{Lu} and add u modifier)
\K - a match reset operator discarding all text matched so far
[0-9]+ - any 1 or more (due to the + quanitifier) digits.
Related
thanks by your help.
my target is use preg_replace + pattern for remove very sample strings.
then only using preg_replace in this string or others, I need remove ANY content into <tag and next symbol >, the pattern is so simple, then:
$x = '#<\w+(\s+[^>]*)>#is';
$s = 'DATA<td class="td1">111</td><td class="td2">222</td>DATA';
preg_match_all($x, $s, $Q);
print_r($Q[1]);
[1] => Array
(
[0] => class="td1"
[1] => class="td2"
)
work greath!
now I try remove strings using the same pattern:
$new_string = '';
$Q = preg_replace($x, "\\1$new_string", $s);
print_r($Q);
result is completely different.
what is bad in my use of preg_replace?
using only preg_replace() how I can remove this strings?
(we can use foreach(...) for remove each string, but where is the error in my code?)
my result expected when I intro this value:
$s = 'DATA<td class="td1">111</td><td class="td2">222</td>DATA';
is this output:
$Q = 'DATA<td>111</td><td>222</td>DATA';
Let's break down your RegEx, #<\w+(\s+[^>]*)>#is, and see if that helps.
# // Start delimiter
< // Literal `<` character
\w+ // One or more word-characters, a-z, A-Z, 0-9 or _
( // Start capturing group
\s+ // One or more spaces
[^>]* // Zero or more characters that are not the literal `>`
) // End capturing group
> // Literal `>` character
# // End delimiter
is // Ignore case and `.` matches all characters including newline
Given the input DATA<td class="td1">DATA this matches <td class="td1"> and captures class="td1". The difference between match and capture is very important.
When you use preg_match you'll see the entire match at index 0, and any subsequent captures at incrementing indexes.
When you use preg_replace the entire match will be replaced. You can use the captures, if you so choose, but you are replacing the match.
I'm going to say that again: whatever you pass as the replacement string will replace the entirety of the found match. If you say $1 or \\=1, you are saying replace the entire match with just the capture.
Going back to the sample after the breakdown, using $1 is the equivalent of calling:
str_replace('<td class="td1">', ' class="td1"', $string);
which you can see here: https://3v4l.org/ZkPFb
To your question "how to change [0] by $new_string", you are doing it correctly, it is your RegEx itself that is wrong. To do what you are trying to do, your pattern must capture the tag itself so that you can say "replace the HTML tag with all of the attributes with just the tag".
As one of my comments noted, this is where you'd invert the capturing. You aren't interesting in capturing the attributes, you are throwing those away. Instead, you are interested in capturing the tag itself:
$string = 'DATA<td class="td1">DATA';
$pattern = '#<(\w+)\s+[^>]*>#is';
echo preg_replace($pattern, '<$1>', $string);
Demo: https://3v4l.org/oIW7d
I have the word AK747, I use regex to detect if a string (at least 2 chars ex: AK) is followed by a number (at least to digits ex: 747).
EDIT : (sorry that I wasn't clear on this guys)
I need to do this above because :
In some case I need to split to match search against AK-747. When I search for string 'AK-747' with keyword 'AK747' it won't find a match unless I use levenshtein in database, so I prefer splitting AK747 to AK and 747.
My code:
$strNumMatch = preg_match('/^[a-zA-Z]{2,}[0-9]{2,}$/',
$value, $match);
if(isset($match[0]))
echo $match[0];
How do I split to array ['AK', '747'] for example with preg_split() or any other way?
$input = 'AK-747';
if (preg_match('/^([a-z]{2,})-?([0-9]{2,})$/i', $input, $result)) {
unset($result[0]);
}
print_r($result);
The output:
Array
(
[1] => AK
[2] => 747
)
You may try this:
preg_match('/[0-9]{2,}/', $value, $matches, PREG_OFFSET_CAPTURE);
$position = $matches[0][1];
$letters = substr($value, 0, $position);
$numbers = substr($value, $position);
This way you get the position of the first number and split there.
EDIT:
Starting from your original approach this could look somewhat like this:
$strNumMatch = preg_match('/^([a-zA-Z]{2,})([0-9]{2,})$/', $value, $match, PREG_OFFSET_CAPTURE);
if($strNumMatch){
$position = $matches[2][1];
$letters = substr($value, 0, $position);
$numbers = substr($value, $position);
$alternative = $letters.'-'.$numbers;
}
preg_split() is a very sensible and direct call since you desire an indexed array containing the two substrings.
Code: (Demo)
$input = 'AK-747';
var_export(preg_split('/[a-z]{2,}\K-?/i',$input));
Output:
array (
0 => 'AK',
1 => '747',
)
The \K means "restart the fullstring match". Effectively, everything to the left of \K is retained as the first element in the result array and everything to right (the optional hyphen) is omitted because it is considered the delimiter. Pattern Demo
Code: (Demo)
I process a small battery of inputs to show what can be done and explain after the snippet.
$inputs=['AK747','AK-747','AK-','AK']; // variations as I understand them
foreach($inputs as $input){
echo "$input returns: ";
var_export(preg_split('/[a-z]{2,}\K-?/i',$input,2,PREG_SPLIT_NO_EMPTY));
echo "\n";
}
Output:
AK747 returns: array (
0 => 'AK',
1 => '747',
)
AK-747 returns: array (
0 => 'AK',
1 => '747',
)
AK- returns: array (
0 => 'AK',
)
AK returns: array (
0 => 'AK',
)
preg_split() takes a pattern that receives a pattern that will match a variable substring and use it as a delimiter. If - were present in every input string then explode('-',$input) would be most appropriate. However, - is optional in this task, so the pattern must allow - to be optional (this is what the ? quantifier does in all of the patterns on this page).
Now, you couldn't just use a pattern like /-?/, that would split the string on every character. To overcome this, you need to tell the regex engine the exact expected location for the optional -. You do this by referencing [a-z]{2,} before the -? (single intended delimiter).
The pattern /[a-z]{2,}-?/i does a fair job of finding the correct location for the optional hyphen, but now the trouble is, the leading letters in the string are included as part of the delimiting substring.
Sometimes, "lookarounds" can be used in regex patterns to match but not consume substrings. A "positive lookbehind" is used to match a preceding substring, however "variable length lookbehinds" are not permitted in php (and most other regex flavors). This is what the invalid pattern would look like: /(?<=[a-z]{2,})-?/i.
The way around this technicality is to "restart the fullstring match" using the \K token (aka a lookbehind alternative) just before the optional hyphen. To correctly target only the intended delimiter, the leading letters must be "matched/consumed" then "discarded" -- that's what \K does.
As for the inclusion of the 3rd and 4th parameter of preg_split()...
I've set the 3rd parameter to 2. This is just like the limit parameter that explode() has. It instructs the function to not make more than 2 output elements. For this case, I could have used NULL or -1 to mean "unlimited", but I could NOT leave the parameter empty -- it must be assigned to allow for the declaration of the 4th parameter.
I've set the 4th parameter to PREG_SPLIT_NO_EMPTY which instructs the function to not generate empty output elements.
Ta-Da!
p.s. a preg_match_all() solution is as easy as using a pipe and two anchors:
$inputs=['AK747','AK-747','AK-','AK']; // variations as I understand them
foreach($inputs as $input){
echo "$input returns: ";
var_export(preg_match_all('/^[a-z]{2,}|\d{2,}$/i',$input,$out)?$out[0]:[]);
echo "\n";
}
// same outputs as above
You can make the - optional with ?.
/([A-Za-z]{2,}-?[0-9]{2,})/
https://regex101.com/r/tIgM4F/1
I have a little problem with getting some numbers from a string.
For example I have this kind of str:
qweqeqe (qweqwe) AASD 213,21 ( -1201,77 EUR )
I need the numbers with comma that are between brackets
Result: -1201,77
The value also can be positive.
I have already managed to get float value, but from all string.
I have this: !\d+(?:\,\d+)?! but it gets all numbers in a str.
IF THERE IS ALWAYS 1 NUMBER INSIDE PARENTHESES...
Here is a two-pass, "readable" approach: extract all parenthetical substrings and then use preg_filter to extract the float values:
$s = "qweqeqe (qweqwe) AASD 213,21 ( -1201,77 EUR )";
preg_match_all('/\([^()]*\)/', $s, $parentheses);
$res = preg_filter('/.*?([+-]?\d+(?:,\d+)?).*/s', '$1', $parentheses[0]);
^^^ ^
See IDEONE demo
Here, we match any symbols before and after float with .*. Note that to preserve the number, we need to use lazy dot matching in the left part (.*?), and we can match anything in the part after the number. As the +/- before the number are optional, use a ? quantifier: [-+]?.
IF THERE CAN BE MORE THAN 1 NUMBER INSIDE PARENTHESES...
It is a less readable one-pass approach:
$s = "qweqeqe (qweqwe) AASD 213,21 ( -1201,77 EUR )";
preg_match_all('/(?:\(|(?!^)\G)[^()]*?([+-]?\d+(?:,\d+)?)(?=[^()]*\))/', $s, $matches);
^^^^
See another IDEONE demo
Here, the regex defines the starting boundary with (?:\(|(?!^)\G) (that is, start looking for the numbers after ( and then after each successful match) and then capture the floats with [^()]*?(\d+(?:,\d+)?) but ensuring we are still inside the parentheses (the rightmost boundary is checked with the (?=[^()]*\)) lookahead).
try this pattern :
$pattern = "#\([\s]*(-{0,1}[0-9]+,[0-9]+)[\s]*[A-Za-z]*[\s]*\)#";
I'm trying to get the string that match with original and with number in the end.
I got these strings:
mod_courts2
mod_courts_config
mod_courts_config2
From these strings I want the one that matches only with "mod_courts" with number in the end.
I'm doing this:
if (strpos($t, "mod_courts") !== FALSE) {
preg_match('/^\w+(\d+)$/U', $t, $match);
echo $match;
}
This returns me "mod_courts2" and "mod_courts_config2", I just want "mod_courts2"
Use the following regex:
/^[a-z]+_[a-z]+(\d+)$/
Explanation:
^ - assert position at the beginning of the string
[a-z]+ - match any alphabet one or more times
_ - match a literal undescore character
[a-z]+ - match any alphabet one or more times
(\d+) - match (and capture) any digit from 0 to 9 one or more times
$ - assert position at the end of the string
Test cases:
$array = array(
'mod_courts2',
'mod_courts_config',
'mod_courts_config2'
);
foreach ($array as $string) {
if(preg_match('/^[a-z]+_[a-z]+(\d+)$/i', $string, $matches)) {
print_r($matches);
}
}
Output:
Array
(
[0] => mod_courts2
[1] => 2
)
Very simply, you can do:
/^(mod_courts\d+)$/
However, if you want exactly the following format: sometext_somettext2, you can use the following regex:
/^([a-zA-Z]+_[a-zA-Z]+\d+)$/
or
/^([^_]+_[^_]+\d+)$/
Demos
http://regex101.com/r/jP8iC1
http://regex101.com/r/tI1uX8
http://regex101.com/r/fX8pO5
^mod_courts\d+$
this should do it
You can just use
^mod_courts[0-9]+$
Meaning mod_courts followed by a number (and only that, thanks to ^$ matching the beginning and end of the string). No need for the strpos check.
Consider example:
$mystring = "us100ch121jp23uk12";
I) I want to change value of jp by adding +1 so that makes the string into
us100ch121jp24uk12
suppose if
II) Is there a way to seperate the numeric part and alphabetic part in the above string into:
[us , 100]
[ch,121]
[jp,24]
[us,12]
my code:
$string = "us100ch121jp23uk12";
$search_for = "us";
$pairs = explode("[]", $string); // I dont know the parameters.
foreach ($pairs as $index=>$pair)
{
$numbers = explode(',',$pair);
if ($numbers[0] == $search_for){
$numbers[1] += 1; // 23 + 1 = 24
$pairs[index] = implode(',',$numbers); //push them back
break;
}
}
$new_string = implode('|',$pairs);
using Evan sir's suggestions
$mystring = "us100ch121jp22uk12";
preg_match_all("/([A-z]+)(\d+)/", $mystring, $output);
//echo $output[0][4];
foreach($output[0] as $key=>$value) {
// echo "[".$value."]";
echo "[".substr($value, 0, 2).",".substr($value, 2, strlen($value) - 2)."]"."<br>";
}
If you use preg_match_all("/([A-z]+)(\d+)/", $string, $output);, it will return an array to $output that contains three arrays. The first array will be country number strings (eg 'us100'). The second will contain country strings (eg 'us'). The third will contain the numbers (eg '100').
Since the second and third arrays will have matching indexes ($output[1][0] will be 'us' and $output[2][0] will be '100'), you could just cycle through those and do whatever you'd like to them.
Here is more information about using regular expressions in PHP. The site also contains information about regular expressions in general, which are a useful tool for any programmer!
You can do it using regular expressions in PHP. See tutorial:
http://w3school.in/w3schools-php-tutorial/php-regular-expression/
Function Description
ereg_replace() The ereg_replace() function finds for string specified by pattern and replaces pattern with replacement if found.
eregi_replace() The eregi_replace() function works similar to ereg_replace(), except that the search for pattern in string is not case sensitive.
preg_replace() The preg_replace() function works similar to ereg_replace(), except that regular expressions can be used in the pattern and replacement input parameters.
preg_match() The preg_match() function finds string of a pattern and returns true if pattern matches false otherwise.
Expression Description
[0-9] It matches any decimal digit from 0 through 9.
[a-z] It matches any character from lowercase a through lowercase z.
[A-Z] It matches any character from uppercase A through uppercase Z.
[a-Z] It matches any character from lowercase a through uppercase Z.
p+ It matches any string containing at least one p.
p* It matches any string containing zero or more p’s.
p? It matches any string containing zero or more p’s. This is just an alternative way to use p*.
p{N} It matches any string containing a sequence of N p’s
p{2,3} It matches any string containing a sequence of two or three p’s.
p{2, } It matches any string containing a sequence of at least two p’s.
p$ It matches any string with p at the end of it.
^p It matches any string with p at the beginning of it.
[^a-zA-Z] It matches any string not containing any of the characters ranging from a through z and A through Z.
p.p It matches any string containing p, followed by any character, in turn followed by another p.
^.{2}$ It matches any string containing exactly two characters.
<b>(.*)</b> It matches any string enclosed within <b> and </b>.
p(hp)* It matches any string containing a p followed by zero or more instances of the sequence hp.
you also can use JavaScript:
http://www.w3schools.com/jsref/jsref_obj_regexp.asp