Split string after each number - php

I have a database full of strings that I'd like to split into an array. Each string contains a list of directions that begin with a letter (U, D, L, R for Up, Down, Left, Right) and a number to tell how far to go in that direction.
Here is an example of one string.
$string = "U29R45U2L5D2L16";
My desired result:
['U29', 'R45', 'U2', 'L5', 'D2', 'L16']
I thought I could just loop through the string, but I don't know how to tell if the number is one or more spaces in length.

You can use preg_split to break up the string, splitting on something which looks like a U,L,D or R followed by numbers and using the PREG_SPLIT_DELIM_CAPTURE to keep the split text:
$string = "U29R45U2L5D2L16";
print_r(preg_split('/([UDLR]\d+)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
Output:
Array (
[0] => U29
[1] => R45
[2] => U2
[3] => L5
[4] => D2
[5] => L16
)
Demo on 3v4l.org

A regular expression should help you:
<?php
$string = "U29R45U2L5D2L16";
preg_match_all("/[A-Z]\d+/", $string, $matches);
var_dump($matches);

Because this task is about text extraction and not about text validation, you can merely split on the zer-width position after one or more digits. In other words, match one or more digits, then forget them with \K so that they are not consumed while splitting.
Code: (Demo)
$string = "U29R45U2L5D2L16";
var_export(
preg_split(
'/\d+\K/',
$string,
0,
PREG_SPLIT_NO_EMPTY
)
);
Output:
array (
0 => 'U29',
1 => 'R45',
2 => 'U2',
3 => 'L5',
4 => 'D2',
5 => 'L16',
)

Related

How do I split the letters and numbers to 2 arrays from a string in PHP

I would like to know how to split both letters and numbers in 2 separate arrays, for example if I have $string = "2w5d15h9s";, then I want it to become
$letters = ["w", "d", "h", "s"];
$numbers = [2, 5, 15, 9];
Anybody got any idea of how to do it?
I'm basically trying to make a ban command and I want to make it so you can specify a time for the ban to expire.
Use preg_split:
$string = "2w5d15h9s";
$letters = preg_split("/\d+/", $string);
array_shift($letters);
print_r($letters);
$numbers = preg_split("/[a-z]+/", $string);
array_pop($numbers);
print_r($numbers);
This prints:
Array
(
[0] => w
[1] => d
[2] => h
[3] => s
)
Array
(
[0] => 2
[1] => 5
[2] => 15
[3] => 9
)
Note that I am using array_shift or array_pop above to remove empty array elements which arise from the regex split. These empty entries occur because, for example, when spitting on digits the first character is a digit, which leaves behind an empty array element to the left of the first actual letter.
Using preg_split() with a PREG_SPLIT_NO_EMPTY flag is the most concise way that I can think of.
In terms of efficiency, preg_ functions are not famous for being fast. Scanning the string should arguably be done in one pass, but these micro-optimization considerations are probably not worth toiling over for such small input strings.
As for the patterns, \d+ means one or more consecutive digit characters and \D+ means one or more consecutive non-digit characters. The 0 is the limit parameter, which merely informs the function to have no limit (split the string as many times as it can).
Code: (Demo)
$string = "2w5d15h9s";
var_export(preg_split('/\d+/', $string, 0, PREG_SPLIT_NO_EMPTY)); // get non-numbers
var_export(preg_split('/\D+/', $string, 0, PREG_SPLIT_NO_EMPTY)); // get numbers
Output:
array (
0 => 'w',
1 => 'd',
2 => 'h',
3 => 's',
)
array (
0 => '2',
1 => '5',
2 => '15',
3 => '9',
)

How to split repeated chars and numbers with preg_split?

I'm trying to solve some problem and I need to split repeated chars and all integers
$code = preg_split('/(.)(?!\1|$)\K/', $code);
I tried this one, but it separate and not repeated chars and not repeated integers , I need only chars
I have a string 'FFF86C6'
I need an array (FFF, 86, C, 6);
with pattern '/(.)(?!\1|$)\K/' returns (FFF, 8, 6, C, 6)
Do you have any idea how to make it?
You can use this regex with preg_match_all:
([A-Za-z])(\1*)|\d+
It looks for a letter, followed by some number of the same character, or some digits. By using preg_match_all we find all matches in the string. Usage in PHP:
$string = "FFF86CR6";
$pieces = preg_match_all('/([A-Za-z])(\1*)|\d+/', $string, $matches);
print_r($matches[0]);
Output:
Array (
[0] => FFF
[1] => 86
[2] => C
[3] => R
[4] => 6
)
Demo on 3v4l.org

How to preg_split without losing a character?

I have a string like this
$string = "Hello; how are you;Hey, I am fine";
$new = preg_split("/;\w/", $string);
print_r($new);
I am trying to split the string only when there is no white-space between the words and ";". But when I do this, I lose the H from Hey. It's probably because the split happens through the recognition of ;H. Could someone tell me how to prevent this?
My output:
$array = [
0 => [
0 => 'Hello; how are you ',
1 => 0,
],
1 => [
0 => 'ey, I am fine',
1 => 21,
],
]
You might use a word boundary \b:
\b;\b
$string = "Hello; how are you;Hey, I am fine";
$new = preg_split("/\b;\b/", $string);
print_r($new);
Demo
Or a negative lookahead and negative lookbehind
(?<! );(?! )
Demo
Lookarounds cost more steps. In terms of pattern efficiency, a word boundary is better and maintains the intended "no-length" character consumption.
In well-formed English, you won't ever have to check for a space before a semi-colon, so only 1 word boundary seems sufficient (I don't know if malformed English is possible because it is not represented in your sample string).
If you want to acquire the offset value, preg_split() has a flag for that.
Code: (Demo)
$string = "Hello; how are you;Hey, I am fine";
$new = preg_split("/;\b/", $string, -1, PREG_SPLIT_OFFSET_CAPTURE);
var_export($new);
Output:
array (
0 =>
array (
0 => 'Hello; how are you',
1 => 0,
),
1 =>
array (
0 => 'Hey, I am fine',
1 => 19,
),
)
Use split with this regex ;(?=\w) then you will not lose the H
You are capturingthe \w in your regex.You dont want that. Therefore, do this:
$new = preg_split("/;(?=\w)/", $string);
A capture group is defined in brackets, but the ?= means match but don't capture.
Check it out here https://3v4l.org/Q77LZ

REGEX Pattern for Validation that check all string is integer and split into single integers

I tried multiple time to make a pattern that can validate given string is natural number and split into single number.
..and lack of understanding of regex, the closest thing that I can imagine is..
^([1-9])([0-9])*$ or ^([1-9])([0-9])([0-9])*$ something like that...
It only generates first, last, and second or last-second split-numbers.
I wonder what I need to know to solve this problem.. thanks
You may use a two step solution like
if (preg_match('~\A\d+\z~', $s)) { // if a string is all digits
print_r(str_split($s)); // Split it into chars
}
See a PHP demo.
A one step regex solution:
(?:\G(?!\A)|\A(?=\d+\z))\d
See the regex demo
Details
(?:\G(?!\A)|\A(?=\d+\z)) - either the end of the previous match (\G(?!\A)) or (|) the start of string (^) that is followed with 1 or more digits up to the end of the string ((?=\d+\z))
\d - a digit.
PHP demo:
$re = '/(?:\G(?!\A)|\A(?=\d+\z))\d/';
$str = '1234567890';
if (preg_match_all($re, $str, $matches)) {
print_r($matches[0]);
}
Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 0
)

PHP regex to extract special string

I am trying to use regex to extract a certain syntax, in my case something like "10.100" or "20.111", in which 2 numbers are separated by dot(.) . So if I provide "a 10.100", it will extract 10.100 from the string. If I provide "a 10.100 20.101", it will extract 10.100 and 20.101.
Until now I have tried to use
preg_match('/^.*([0-9]{1,2})[^\.]([0-9]{1,4}).*$/', $message, $array);
but still no luck. Please provide any suggestion because I don't have strong regex knowledge. Thanks.
You may use
\b[0-9]{1,2}\.[0-9]{1,4}\b
See the regex demo.
Details:
\b - a leading word boundary
[0-9]{1,2} - 1 or 2 digits
\. - a dot
[0-9]{1,4} - 1 to 4 digits
\b - a trailing word boundary.
If you do not care about the whole word option, just remove \b. Also, to match just 1 or more digits, you may use + instead of the limiting quantifiers. So, perhaps
[0-9]+\.[0-9]+
will also work for you.
See a PHP demo:
$re = '/[0-9]+\.[0-9]+/';
$str = 'I am trying to use regex to extract a certain syntax, in my case something like "10.100" or "20.111", in which 2 numbers are separated by dot(.) . So if I provide "a 10.100", it will extract 10.100 from the string. If I provide "a 10.100 20.101", it will extract 10.100 and 20.101.';
preg_match_all($re, $str, $matches);
print_r($matches[0]);
Output:
Array
(
[0] => 10.100
[1] => 20.111
[2] => 10.100
[3] => 10.100
[4] => 10.100
[5] => 20.101
[6] => 10.100
[7] => 20.101
)
Regex: /\d+(?:\.\d+)/
1. \d+ for matching digits one or more.
2. (?:\.\d+) for matching digits followed by . like .1234
Try this code snippet here
<?php
ini_set('display_errors', 1);
$string='a 10.100 20.101';
preg_match_all('/\d+(?:\.\d+)/', $string, $array);
print_r($array);
Output:
Array
(
[0] => Array
(
[0] => 10.100
[1] => 20.101
)
)
$decimals = "10.5 100.50 10.250";
preg_match_all('/\b[\d]{2}\.\d+\b/', $decimals, $output);
print_r($output);
Output:
Array
(
[0] => 10.5
[1] => 10.250
)
Regex Demo | Php Demo

Categories