I have a string like "some words 12345cm some more words"
and I want to extract the 12345cm bit from that string. So I get the position of the first number:
$position_of_first_number = strcspn( "some words 12345cm some more words" , '0123456789' );
Then the position of the first space after $position_of_first_number
$position_of_space_after_numbers = strpos("some words 12345cm some more words", " ", $position_of_first_number);
Then I want to have a function which return the portion of the string between $position_of_first_number and $position_of_space_after_numbers.
How do I do it?
You can use the substr function. Note that it takes a starting position and a length, which you can calculate as the difference between the start and end positions.
Since you are looking for a pattern like blank-digits-letters-blank, I would recommend a regular expression using preg_match:
$s = "some words 12345cm some more words";
preg_match("/\s(?P<result>\d+[^\W\d_]+)\s/", $s, $matches);
echo $matches["result"];
12345cm
Explaining the pattern:
"/.../" limits the pattern in PHP
\s matches any whitespace character
(?P<name>...) names the following pattern
\d+ matches 1 or more digits
[^\W\d_]+ matches 1 or more Unicode-letters (i.e. any character that is not a non-alphanumeric character; see this answer)
Related
I have strings with numbers-dashes sub-strings. I want to find these sub-strings and replace them after some modifications.
For example, the string is like:
This is the string number 123-45-6789-0 which contains 12-34567.
Now I want to find sub-strings of numbers-dashes (123-45-6789-0 and 12-34567) and replace them with the modified sub-strings. For example the final string would be like this:
This is the modified string number 0-6789-45-123 which contains 34567-12.
I have already tried preg_match_all(string $pattern, string $subject, array &$matches) with:
$pattern = '/-*\d+-*/';
but it gives me an array of numbers each one with a dash, like this:
$matches = [123-, 45-, 6789-, 0, 12-, 34567]
whereas, I want an array of two sub-strings, like this:
$matches = [0 => 123-45-6789-0, 1 => 12-34567]
in order to do modifications and replacements (using str_replace()), separately.
Which pattern and methods should I use for these purpose?
Thanks in advance.
You may use \d+(?:-\d+)+ regex with a preg_replace_callback` function:
$str = 'This is the string number 123-45-6789-0 which contains 12-34567.';
echo preg_replace_callback('~\d+(?:-\d+)+~', function($m) {
return implode('-', array_reverse(explode('-', $m[0]))); }
,$str);
// => This is the string number 0-6789-45-123 which contains 34567-12.
See PHP demo and the regex demo.
The \d+(?:-\d+)+ pattern matches
\d+ - 1+ digits
(?:-\d+)+ - 1 or more occurrences of - and 1+ digits sequences.
$m is a match array, $m[0] holds the match value. With explode, the string is split with -, then the array is reversed, and then joined back with implode.
I Have one string like below.
$string = "2346#$ABSC$%###234567";
Now I want last character from this string that is not numeric or special character, It should be only A-a to Z-z.
Means, I need only "C" from this string.
I have try this formula:
substr($string, -1);
You should look into regular expressions using something like preg_match()
An expression like this would match:
/([a-z])[^a-z]*$/i
It means:
([a-z]) Capture an a-z character (the i at the end makes it case-insensitive)
[^a-z]*$ followed by 0 or more non a-z characters until the end of the string
See an example.
This should work for you:
(Here I just replace everything expect a-zA-Z with an empty string. After this I just access the last character)
<?php
$string = '2346#$ABSC$%###234567';
$string = preg_replace("/[^a-zA-Z]/", "", $string);
echo $string[strlen($string)-1];
?>
output:
C
The proper regex is: ([a-z])[^a-z]*$
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
I am trying to use preg_match to find a certain word in a string of text.
$pattern = "/" . $myword . "/i";
This pattern will find the word "car" inside "cartoon"...
I need just matches where the certain word appears.
P.S The word may be anywhere inside the text.
Thanks
Wrap your regex with word-boundaries:
$pattern = "/\b" . $myword . "\b/i";
or, if your $myword may contain regex-meta-chars, do:
$pattern = "/\b" . preg_quote($myword) . "\b/i";
Try this:
$pattern = "/\b" . $myword . "\b/i";
In regular expressions, the \b escape character represents a "word boundary" character. By wrapping your search term within these boundary matches, you ensure that you will only match the word itself.
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, $subject, $matches, PREenter code hereG_OFFSET_CAPTURE, 3);
print_r($matches);
pattern
The pattern to search for, as a string.
subject
The input string.
matches
If matches is provided, then it is filled with the results of search. $matches[0] will contain the text that matched the full pattern, $matches[1] will have the text that matched the first captured parenthesized subpattern, and so on.
flags
flags can be the following flag:
PREG_OFFSET_CAPTURE
If this flag is passed, for every occurring match the appendant string offset will also be returned. Note that this changes the value of matches into an array where every element is an array consisting of the matched string at offset 0 and its string offset into subject at offset 1.
offset
Normally, the search starts from the beginning of the subject string. The optional parameter offset can be used to specify the alternate place from which to start the search (in bytes).
Example:
if (preg_match('/;/', $_POST['value_code']))
{
$input_error = 1;
display_error(_("The semicolon can not be used in the value code."));
set_focus('value_code');
}
I have a string like:
$Order_num = "0982asdlkj";
How can I split that into the 2 variables, with the number as one element and then another variable with the letter element?
The number element can be any length from 1 to 4 say and the letter element fills the rest to make every order_num 10 characters long in total.
I have found the php explode function...but don't know how to make it in my case because the number of numbers is between 1 and 4 and the letters are random after that, so no way to split at a particular letter.
You can use preg_split using lookahead and lookbehind:
print_r(preg_split('#(?<=\d)(?=[a-z])#i', "0982asdlkj"));
prints
Array
(
[0] => 0982
[1] => asdlkj
)
This only works if the letter part really only contains letters and no digits.
Update:
Just to clarify what is going on here:
The regular expressions looks at every position and if a digit is before that position ((?<=\d)) and a letter after it ((?=[a-z])), then it matches and the string gets split at this position. The whole thing is case-insensitive (i).
Use preg_match() with a regular expression of (\d+)([a-zA-Z]+). If you want to limit the number of digits to 1-4 and letters to 6-9, change it to (\d+{1,4})([a-zA-Z]{6,9}).
preg_match("/(\\d+)([a-zA-Z]+)/", "0982asdlkj", $matches);
print("Integer component: " . $matches[1] . "\n");
print("Letter component: " . $matches[2] . "\n");
Outputs:
Integer component: 0982
Letter component: asdlkj
http://ideone.com/SKtKs
You can also do it using preg_split by splitting your input at the point which between the digits and the letters:
list($num,$alpha) = preg_split('/(?<=\d)(?=[a-z]+)/i',$Order_num);
You can use a regex for that.
preg_match('/(\d{1,4})([a-z]+)/i', $str, $matches);
array_shift($matches);
list($num, $alpha) = $matches;
Check this out
<?php
$Order_num = "0982asdlkj";
$split=split("[0-9]",$Order_num);
$alpha=$split[(sizeof($split))-1];
$number=explode($alpha, $Order_num);
echo "Alpha -".$alpha."<br>";
echo "Number-".$number[0];
?>
with regards
wazzy
My preferred approach would be sscanf() because it is concise, doesn't need regex, offers the ability to cast the numeric segment as integer type, and doesn't generate needless fullstring matches like preg_match(). %s does rely, though, on the fact that there will be no whitespaces in the letters segment of the string.
Demo
$Order_num = "0982asdlkj";
var_export (
sscanf($Order_num, '%d%s')
);
This can also be set up to declare individual variables.
sscanf($Order_num, '%d%s', $numbers, $letters)
If wanting to use a preg_ function, preg_split() is most appropriate, but I wouldn't use expensive lookarounds. Match the digits, then forget them (with \K). This will split the string without consuming any characters. Demo
var_export (
preg_split('/\d+\K/', $Order_num)
);
To assign variables, use "symmetric array destructuring".
[$numbers, $letters] = preg_split('/\d+\K/', $Order_num);
Beyond these single function approaches, there will be MANY two function approaches like:
$numbers = rtrim($Order_num, 'a..z');
$letters = ltrim($Order_num, '0..9');
But I wouldn't use them in a professional script because they lack elegance.