I have different strings, contains phone numbers like this:
New order to car wash #663. Customer number is 7962555443. Thank you.
or
New order to car wash #663. Customer number is 50414. Thank you, bye.
or
New order to car wash #663. A phone number to connect with the customer is 905488739038.
I need this:
New order to car wash #663. Customer number is 7 9 6 2 5 5 5 4 4 3. Thank you.
or
New order to car wash #663. Customer number is 5 0 4 1 4. Thank you, bye.
or
New order to car wash #663. A phone number to connect with the customer is 9 0 5 4 8 8 7 3 9 0 3 8.
I need to separate numbers contains more than 3 symbols.
preg_replace alone without any callback function would be sufficient.
preg_replace('~#\d+(*SKIP)(*F)|(?<=\d)(?=\d)~', ' ', $str);
DEMO
#\d+(*SKIP)(*F) Matches and discards all the numbers which starts with #.
| OR
(?<=\d)(?=\d) Now from the remaining string, this would match the boundary which exists between two digits.
Now by replacing the matched boundary with space will give you the desired output.
You could use a callback for this:
$str = preg_replace_callback('~\b\d{4,}~',
function($m) {
return implode(' ', str_split($m[0]));
}, $str);
eval.in
Also can do this by using the \G anchor. Replace with matched digit + space: "$0 "
I need to separate numbers contains more than 3 symbols.
$str = preg_replace('~\b\d(?=\d{3})|\G\d\B~', "$0 ", $str);
\b\d matches a word-boundary \b followed by a digit (\d is a short for [0-9])
(?=\d{3}) Using a lookahead to check next 3 after first \d are digits too
|\G\d\B OR match a digit at \G end of previous match followed by \B non word-boundary
See test at regex101 or eval.in
As an alternative could also replace first digit after a \h horizontal space: \h\d|\G\d\B
Try this.
$phonenumber="7962555443";
$formatted = implode(' ',str_split($phonenumber));
You can use implode you just need to use str_split first which converts the string to an array:
$number="905488739038";
$formatted = implode(' ',str_split($number));
echo $formatted;
Output:
9 0 5 4 8 8 7 3 9 0 3 8
Ref: http://www.php.net/manual/en/function.str-split.php
You may try this regex as well:
((?:(?:\d)\s?){4,})
It will capture all the number having length four or more. Also you need to do an additional step to remove spaces from the matches from the results like this:
7 9 6 2 5 5 5 4 4 3
Demo
Related
I would like to replace the first 5 digits or the last 4 of the id card, it always comes before a "-" and a space
String:
$string1 = "** GALLARDO SERGIO - 74276932M";
$string2 = "** MONTOLIA ANTONIO - 74736619E";
I have two options to show the result, the first 5 numbers of the id card or the last 4
$result1= "** GALLARDO SERGIO - *****932M";
$result2= "** MONTOLIA ANTONIO - 74736****";
for the second option I have used a substr () but it does not work if a string comes with another type of text
$result= substr($string1, 0, -4) . "****";
thanks
You can leverage
preg_replace('~^(.*-\h+)\d{5}~', '$1*****', $text);
The regex matches
^ - start of string
(.*-\h+) - Capturing group 1: any zero or more chars as many as possible, up to the rightmost - and one or more horizontal whitespaces
\d{5} - five digits.
In the replacement pattern, $1 refers to the value of Group 1.
See the regex demo.
I'm trying to pull two numbers from a variable($text) and then multiply them and output the results. The two numbers can be ints and floats.
When I try:
$text = "1 photograph - b&w - 2 x 5 in."
I get: The image area is 10 Which is what I want
<?php
$text = "1 photograph - b&w - 2 x 5.5 in.";
if (preg_match("/[[:digit:]]*\ x [[:digit:]]* /", $text, $match)) :
print_r($match);
$dimensions = trim($match[0]);
$dimensions = explode(" x ",$dimensions);
$image_area = (($dimensions[0]) * ($dimensions[1]));
echo 'The image area is '.($image_area);
endif;
?>
But when I try:
$text = "1 photograph - b&w - 2 x 5.5 in."
I get a blank screen
How would I output floats?
my code and output:http://sandbox.onlinephpfunctions.com/code/4b45219fdcb7864442268459621bb506c24ce78f
You have an extra space at the end of the regex, which would break it. Remove it, and it would match 2 x 5. You should be able to extend it further by adding \. to each side of the regex:
if (preg_match("/[[:digit:]\.]*\ x [[:digit:]\.]*/", $text, $match)) {
The regex expression isn't robust enough to distinguish between whole numbers and decimal numbers. The [[:digit:]] operator only matches characters 0-9.
This site is useful for creating and testing regex:
https://regex101.com/
Your regex does not match. You want:
/\d+(?:\.\d+)? x \d+(?:\.\d+)? /
1 or more digits, (optional: dot, 1 or more digits), space, x, space, 1 or more digits, (optional: dot, 1 or more digits), space
test online
Pattern : '/x(?: (\d))+/i'
String : x 1 2 3 4 5
Returned : 1 Match Position[11-13] '5'
I want to catch all possible repetitions, or does it return 1 result per group?
I want the following :
Desired Output:
MATCH 1
1. [4-5] `1`
2. [6-7] `2`
3. [8-9] `3`
4. [10-11] `4`
5. [12-13] `5`
Which I was able to achieve just by copy pasting the group, but this is not what I want. I want a dynamic group capturing
Pattern: x(?: (\d))(?: (\d))(?: (\d))(?: (\d))(?: (\d))
You cannot use one group to capture multiple texts and then access them with PCRE. Instead, you can either match the whole substring with \d+(?:\s+\d+)* and then split with space:
$re2 = '~\d+(?:\s+\d+)*~';
if (preg_match($re2, $str, $match2)) {
print_r(preg_split("/\\s+/", $match2[0]));
}
Alternatively, use a \G based regex to return multiple matches:
(?:x|(?!^)\G)\s*\K\d+
See demo
Here is a PHP demo:
$str = "x 1 2 3 4 5";
$re1 = '~(?:x|(?!^)\G)\s*\K\d+~';
preg_match_all($re1, $str, $matches);
var_dump($matches);
Here, (?:x|(?!^)\G) is acting as a leading boundary (match the whitespaces and digits only after x or each successful match). When the digits are encountered, all the characters matched so far are omitted with the \K operator.
I am in a situation that iIneed to break the line 'Havenlaan 86C Bus 12' into two parts
$str = 'Havenlaan 86C Bus 12';
$regex = '/[ ^\d]/';
$flags = PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY;
$exploded = preg_split( $regex,$str, 2, $flags);
print_r($exploded);
The above code sucessfully does the job and the out out is below.
Havenlaan
86C Bus 12
BUT when I change the string to $str = 'Havenlaan ABC 86C Bus 12';
I get
1. Havenlaan
2. ABC 86C Bus 12
What I need is
1. Havenlaan ABC
2. 86C Bus 12
ie. first output should be pure string and second one should start with a number and can be followed by characters.
You can use lookahead
$regex = '/(?=\d)/';
This would split at the first occurrence of a digit (with the limit specified as 2).
If you just split twice, use /(?=\d)/
/ \d/ works as a delimiter.
[ ^\d] matches only a single character of either a space or ^\d not-a-digit.
I'm trying to split (with preg_split) a text with a lot of foreign chars and digits into words and numbers with length >= 2 and without ponctuation.
Now I have this code but it only split into words without taking account digits and length >= 2 for all.
How can I do please?
$text = 'abc 文 字化け, efg Yukarda mavi gök, asağıda yağız yer yaratıldıkta; (1998 m. siejės 7 d.). Ton pate dėina bandomkojė бойынша бірінші орында тұр (79.65 %), айына 41';
$splitted = preg_split('#\P{L}+#u', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
Expected result should be : array('abc', '字化け', 'efg', 'Yukarda', 'mavi', 'gök', 'asağıda', 'yağız', 'yer', 'yaratıldıkta', '1998', 'siejės', 'Ton', 'pate', 'dėina', 'bandomkojė', 'бойынша', 'бірінші', 'орында', 'тұр', '79.65', 'айына', '41');
NB : already tried with these docs link1 & link2 but i can't get it works :-/
Use preg_match_all instead, then you can check the length condition (that is hard to do with preg_split, but not impossible):
$text = 'abc 文 字化け, efg Yukarda mavi gök, asağıda yağız yer yaratıldıkta; (1998 m. siejės 7 d.). Ton pate dėina bandomkojė бойынша бірінші орында тұр (79.65 %), айына 41';
preg_match_all('~\p{L}{2,}+|\d{2,}+(?>\.\d++)?|\d\.\d++~u',$text,$matches);
print_r($matches);
explanation:
p{L}{2,}+ # letter 2 or more times
| # OR
\d{2,}+ # digit 2 or more times
(?>\.\d++)? # can be a decimal number
| # OR
\d\.\d++ # single digit MUST be followed by at least a decimal
# (length constraint)
With a little hack to match digits separated by dot before matching only digits as part of the word:
preg_match_all("#(?:\d+\.\d+|\w{2,})#u", $text, $matches);
$splitted = $matches[0];
http://codepad.viper-7.com/X7Ln1V
Splitting CJK into "words" is kind of meaningless. Each character is a word. If you use whitespace the you split into phrases.
So it depends on what you're actually trying to accomplish. If you're indexing text, then you need to consider bigrams and/or CJK idioms.