preg_match to match substring of three numbers consecutively? - php

I have a string $text_arr="101104105106109111112113114116117120122123124"
fairly big string
If i want to split three numbers from them like 101,104,105 and store them in $array .What should i do?
I tried doing this:
preg_match_all('/[0-9]{3}$/',"$text_arr",$array);

The easiest way to do this is with preg_split()Docs:
$result = preg_split('/(\d{3})/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
See it working, or the result:
Array
(
[0] => 101
[1] => 104
[2] => 105
[3] => 106
[4] => 109
[5] => 111
[6] => 112
[7] => 113
[8] => 114
[9] => 116
[10] => 117
[11] => 120
[12] => 122
[13] => 123
[14] => 124
)

Though you could use a regular expression for this, it might be more performant to use a simple, standard function:
$groups = str_split($numbers, 3);//returns array you want
Read all about it here

You have to remove the ends with $ from your expression, it is causing to return only one result
try like this
preg_match_all('/[0-9]{3}/', $text_arr, $array);
check this working here

Choose this simplest code
<?php
$string = "101104105106109111112113114116117120122123124";
$parts = str_split($string, 3);
$res=implode(',',$parts);
echo($res);
?>

Related

php split / cluster binary into chunks based on next 1 in cycle

I need to figure out a method using PHP to chunk the 1's and 0's into sections.
1001 would look like: array(100,1)
1001110110010011 would look like: array(100,1,1,10,1,100,100,1,1)
It gets different when the sequence starts with 0's... I would like it to segment the first 0's into their own blocks until the first 1 is reached)
00110110 would look like (0,0,1,10,1,10)
How would this be done with PHP?
You can use preg_match_all to split your string, using the following regex:
10*|0
This matches either a 1 followed by some number of 0s, or a 0. Since a regex always tries to match the parts of an alternation in the order they occur, the second part will only match 0s that are not preceded by a 1, that is those at the start of the string. PHP usage:
$beatstr = '1001110110010011';
preg_match_all('/10*|0/', $beatstr, $m);
print_r($m);
$beatstr = '00110110';
preg_match_all('/10*|0/', $beatstr, $m);
print_r($m);
Output:
Array
(
[0] => Array
(
[0] => 100
[1] => 1
[2] => 1
[3] => 10
[4] => 1
[5] => 100
[6] => 100
[7] => 1
[8] => 1
)
)
Array
(
[0] => Array
(
[0] => 0
[1] => 0
[2] => 1
[3] => 10
[4] => 1
[5] => 10
)
)
Demo on 3v4l.org

Splitting a single string to an array on more than one delimiter

Is it possible to explode the following:
08 1.2/3(1(1)2.1-1
to an array of {08, 1, 2, 3, 1, 1, 2, 1, 1}?
I tried using preg_split("/ (\s|\.|\-|\(|\)) /g", '08 1.2/3(1(1)2.1-1') but it returned nothing. I tried checking my regex here and it matched well. What am I missing here?
You should use a character class containing all the delimiters which you want to use for splitting. Regex character classes appear inside [...]:
<?php
$keywords = preg_split("/[\s,\/().-]+/", '08 1.2/3(1(1)2.1-1');
print_r($keywords);
Result:
Array ( [0] => 08 [1] => 1 [2] => 2 [3] => 3 [4] => 1 [5] => 1 [6] => 2 [7] => 1 [8] => 1 )
You can use preg_match_all():
$str = '08 1.2/3(1(1)2.1-1';
preg_match_all('!\d+!', $str, $matches);
print_r($matches);

Trying to learn to write a RegExp for PHP

I am trying to learn how to write a RegEx but it seems all my searches lead to unclear information. So my question is two fold.
Does anyone have a good source on how a newbie could learn to write RegExs?
How could I write a RegEx that breaks the string 1y 311d 16h 42m into variables?
I'm looking to take the above text string and break it into something like:
$duration[years] = 1;
$duration[days] = 311;
$duration[hours] = 16;
$duration[minutes] = 42;
Please note the total digits might may not always be the same for example it could be two digit days. Something like. 25d or some could be omitted. I might just get days and hours. Lastly the order might change. Perhaps it is written days then years etc.
I know I could do this easily with an explode function and strpos, but I really want to learn Regex so I am using this as an example as I understand they can be very powerful for things like this.
1) Some useful pages:
http://www.regular-expressions.info
https://regex101.com/
http://php.net/manual/en/book.pcre.php
2) Specifically, this:
$pattern = '/(?:(?P<years>\d+)y\s*)?(?:(?P<days>\d+)d\s*)?(?:(?P<hours>\d+)h\s*)?(?:(?P<minutes>\d+)m\s*)?/';
preg_match($pattern, '1y 311d 16h 42m', $duration);
print_r($duration);
// Array
// (
// [0] => 1y 311d 16h 42m
// [years] => 1
// [1] => 1
// [days] => 311
// [2] => 311
// [hours] => 16
// [3] => 16
// [minutes] => 42
// [4] => 42
// )
preg_match($pattern, '311d 42m', $duration);
print_r($duration);
// Array
// (
// [0] => 1y 311d 16h 42m
// [years] =>
// [1] =>
// [days] => 311
// [2] => 311
// [hours] =>
// [3] =>
// [minutes] => 42
// [4] => 42
// )
This will give fixed order though. If the order can change, regexp is not a good tool. It's still possible in this case, but rather awkward. Here it is:
$pattern = "/(?=.*?(?:(?P<years>\d+)y|$))(?=.*?(?:(?P<days>\d+)d|$))(?=.*?(?:(?P<hours>\d+)h|$))(?=.*?(?:(?P<minutes>\d+)m|$))/";
preg_match($pattern, '311d 16h 1y', $duration);
print_r($duration);
// Array
// (
// [0] =>
// [years] => 1
// [1] => 1
// [days] => 311
// [2] => 311
// [hours] => 16
// [3] => 16
// )
Entering these patterns (without the leading and trailing slashes) in regex101 will give you the explanation of what exactly it is trying to match. Find other examples from the regex tag questions and enter them as well, and try to see how they work. Experience is the best teacher.

Changing an array to a json with json_encode

I have this array:
Array
(
[1] => 20130701 4 4 3060 1
[2] => 20130702 270 757 13812810 4
[3] => 20130703 5 123 3894971 2
[4] => 20130704 290 478 5119617 1
[5] => 20130705 88 98 189791 2
[6] => 20130708 9 73 564627 1
[7] => 20130722 6102 11992 41974701 1
[8] => 20130723 6397 11021 40522224 1
[9] => 20130725 4644 9336 49167728 2
[10] => 20130726 4891 10157 33516844 3
[11] => 20130727 123 319 2538226 3
[12] => 20130728 451 801 1078705 2
[13] => 20130729 13609 30407 95551827 5
[14] => 20130730 6354 17550 272794650 158
[15] => 20130731 6270 18456 269468599 174
)
I'm trying to change the output in order to show it in a chart, do i change it into a json:
foreach ($day as $key => $value) {
$value = explode(" ", $value) ;
$day[$key] = $value ;
$charts[] = array(substr($value[0],0,4).'-'.substr($value[0],4,2).'-'.substr($value[0],6,2),$value[4]) ;
}
$charts = json_encode($charts, JSON_NUMERIC_CHECK) ;
But it displays me this :
[["2013-07-01","1\r"],["2013-07-02","4\r"],["2013-07-03","2\r"],["2013-07-04","1\r"],["2013-07-05","2\r"],["2013-07-08","1\r"],["2013-07-22","1\r"],["2013-07-23","1\r"],["2013-07-25","2\r"],["2013-07-26","3\r"],["2013-07-27","3\r"],["2013-07-28","2\r"],["2013-07-29","5\r"],["2013-07-30","158\r"],["2013-07-31","174\r"]]
why \r does show? any way I can prevent this ?
try
$charts[] = array(substr($value[0],0,4).'-'.substr($value[0],4,2).'-'.substr($value[0],6,2),substr($value[4],0, -1)) ;
You have return characters at the end of your array
[3] => 20130703 5 123 3894971 2\r
They are not visible because \n = new line \r returns the pointer to the beginning of the line.
Your best bet is to use trim() on every element:
foreach ($day as $key => $value) {
$value = explode(" ", trim($value));
$day[$key] = trim($value) ;
$charts[] = array(trim(substr($value[0],0,4).'-'.substr($value[0],4,2).'-'.substr($value[0],6,2),$value[4])) ;
}
It's even better on numbers to use intval(), which ensures datatype to be integer and removes blankspaces, returns, ... too.

How to manipulate complex strings in php?

I am trying to group bunch of texts from a string and create an array for it.
The string is something like this:
<em>string</em> and the <em>test</em> here.
tableBegin rowNumber:2, columnNumber:2 11 22 33 44 tableEnd
<em>end</em> text here
I was hoping to get an array like the following results
array (0 => '<em>string</em> and the <em>test</em> here.',
1=>'rowNumber:5',
2=>'columnNumber:3',
3=>'11',
4=>'22',
5=>'33',
6=>'44'
7=>'<em>end</em> text here')
11,22,33,44 are the table cell data the user enters. I want to make them have unique index but keep the rest of texts together.
tableBegin and tableEnd are just the check for the table cell data
Any help or tips? Thanks a lot!
You may try the following, note that you need PHP 5.3+:
$string = '<em>string</em> and the <em>test</em> here.
tableBegin rowNumber:2, columnNumber:2 11 22 33 44 tableEnd
SOme other text
tableBegin rowNumber:3, columnNumber:3 11 22 33 44 55 tableEnd
<em>end</em> text here';
$array = array();
preg_replace_callback('#tableBegin\s*(.*?)\s*tableEnd\s*|.*?(?=tableBegin|$)#s', function($m)use(&$array){
if(isset($m[1])){ // If group 1 exists, which means if the table is matched
$array = array_merge($array, preg_split('#[\s,]+#s', $m[1])); // add the splitted string to the array
// split by one or more whitespace or comma --^
}else{// Else just add everything that's matched
if(!empty($m[0])){
$array[] = $m[0];
}
}
}, $string);
print_r($array);
Output
Array
(
[0] => string and the test here.
[1] => rowNumber:2
[2] => columnNumber:2
[3] => 11
[4] => 22
[5] => 33
[6] => 44
[7] => SOme other text
[8] => rowNumber:3
[9] => columnNumber:3
[10] => 11
[11] => 22
[12] => 33
[13] => 44
[14] => 55
[15] => end text here
)
Regex explanation
tableBegin : match tableBegin
\s* : match a whitespace zero or more times
(.*?) : match everything ungreedy and put it in group 1
\s* : match a whitespace zero or more times
tableEnd : match tableEnd
\s* : match a whitespace zero or more times
| : or
.*?(?=tableBegin|$) : match everything until tableBegin or end of line
The s modifier : make dots also match newlines
Here is the ugly way to do it, if you can't find a Regex guru out ther.
So, this is your text
$string = "<em>string</em> and the <em>test</em> here.
tableBegin rowNumber:2, columnNumber:2 11 22 33 44 tableEnd
<em>end</em> text here";
And this is my code
$E = explode(' ', $string);
$A = $E[0].$E[1].$E[2].$E[3].$E[4].$E[5];
$B = $E[17].$E[18].$E[19];
$All = [$A, $E[8],$E[9], $E[11], $E[12], $E[13], $E[14], $B];
print_r($All);
And this is the output
Array
(
[0] => stringandthetesthere.
[1] => rowNumber:2,
[2] => columnNumber:2
[3] => 11
[4] => 22
[5] => 33
[6] => 44
[7] => endtexthere
)
off-course, the <em> tags won't be visible, unless view the source code.

Categories