I have the following string example: 034a412f500535454e5
Here I would get the 500 out.
The search-string has always 8 digits in front and 8 digits behind. The "500" can have a different lenght of digits (p.ex. 12345).
With a lot of trial end error I found that
preg_match('/(.{8})(.*)(.{13})/', $a, $matches);
It works. But I tink that not the way it is.
I do not understand why the left side has {8} and the right is {13}.
I get my String at following:
$lastInsertedId = 500;
$numArray = str_split(bin2hex(random_bytes(8)), 8);
$newArray = [$numArray[0],$lastInsertedId,$numArray[1]];
$a = vsprintf('%s%s%s',$newArray);
by using:
preg_match('/^.{8}\K.*(?=.{8}$)/', $a, $matches);
the result is 50053545. It will not gives the right value back.
by using:
preg_match('/^.{8}\K.*(?=.{8}$)/', '034a412f500535454e5', $matches);
it gives 500 back
Whats wrong?
gettype($a) gives string back.
I'am on php 8.1.13
If you want to do that with a regex, you can use
^.{8}\K.*(?=.{8}$)
See the regex demo. Use the s flag if the string contains line breaks.
Details
^ - start of string
.{8} - eight chars
\K - omit what was matched so far
.* - any zero or more chars
(?=.{8}$) - a positive lookahead that requires any eight chars followed by the end of string location to appear immediately to the right of the current location.
Also, consider using substr:
$text = '034a412f500535454e5';
echo substr($text, 8, strlen($text)-16); // => 500
vsprintf gives a wrong number of digits back.
strlen('034a412f500535454e5') gives 19
strlen($a) gives 25.
I'am using sprintf instead.
Related
i can't figure out this thing i think it possible with only one pattern, please help me improve.
I have this string 2 / 3 items and i wont receive only 2 / 3
Items can also be write in cirillic so 2 / 3 штуки
So i think the best way is use \D all non digit (result 23)
But this delete also the slash that i want to keep, how i can do?
// this was my solution for now,
// but it not complete for cirillic cause i have an error
// it return: 2 / 3 �
// maybe is something with encoding?
preg_replace('#[a-zA-Zа-яА-Я]*#', '', '2 / 3 штуки');
// so i chose to do this, but doesn't know how to keep slash
preg_replace('#[\D]*#', '', '2 / 3 штуки');
// it return: 23
# How to get 2 / 3 ?
You can use
if (preg_match('~\d+\s*/\s*\d+~u', $text, $match)) {
echo $match[0];
}
Also, if the fraction part is optional, use
preg_match('~\d+(?:\s*/\s*\d+)?~u', $text, $match)
And if you need to extract all occurrences, use preg_match_all:
preg_match_all('~\d+(?:\s*/\s*\d+)?~u', $text, $matches)
See the regex demo and the PHP demo. Note that preg_match extracts the match rather than remove it (as is the case with preg_replace).
Pattern details
\d+ - one or more digits
- \s*/\s* - / enclosed with zero or more whitespaces
\d+ - one or more digits
Note that u is used in case the whitespace in your string can be other than regular ASCII whitespace, like \xA0.
I've asked and it was answered but now, after years, it doesn't work.
I've even tried online regex validators. Not sure what is going on.
Version: PHP 7.0.30 on 64Bit OS
The string should only allow digits with commas.
No commas in the beginning or end.
Spaces between commas is ok but I'd rather not allow it.
The following isn't passing
My regex is:
$DateInvoicedIDs = "1031,453,808,387,111,342,962,706,251,442,362,858,950,738,310,288,99,665,1023,30,894,112,132,148,347,895,382,94,766,683,276,1104,658,34,348,235,786,769,2";
$reg = '/[0-9\s]+(,[0-9\s]+)*[0-9]$/';
if ( preg_match($reg, $DateInvoicedIDs) ) {
echo = $DateInvoicedIDs;
} else { echo "false"; }
I'm using preg_match and getting false.
Any idea?
Test your string and pattern # https://regex101.com/r/3TVmOv/1
When that loads, you will see that there is no match highlighted.
Then add a digit to the end of your string and Whalla! This is because (,[0-9\s]+)* is matching the final 2 and [0-9]$ cannot be satisfied because another digit is required.
If I understand your logic/requirements, I think I'd use ~^\d+(?:\s*,\s*\d+)*$~
This improves the validation because it doesn't allow a mixture of digits and spaces between commas like: 2, 3 4 56, 72 I don't think you want spaces in your comma-separated numerical values.
Pattern Demo
Code: (Demo)
$DateInvoicedIDs = "1031,453,808,387,111,342,962,706,251,442,362,858,950,738,310,288,99,665,1023,30,894,112,132,148,347,895,382,94,766,683,276,1104,658,34,348,235,786,769,2";
$reg = '/^\d+(?:\s*,\s*\d+)*$/';
if (preg_match($reg, $DateInvoicedIDs)) {
echo $DateInvoicedIDs;
} else {
echo "false";
}
It is not matching because of the last [0-9] in your regex. The * in (,[0-9\s]+)* is a greedy match which means that it is consuming all commas followed by digits in your string. There is nothing left after to match against the last [0-9].
So you probably want to reduce your regex to '/[0-9\s]+(,[0-9\s]+)*$/.
The last part of your regex [0-9]$ is what's causing it to fail:
[0-9\s]+ is matching the first number only 1031,
(,[0-9\s]+)* is covering everything until ,2 because it's a single number right after a comma which is what it's looking for
Then [0-9]$ is trying to find one more number but it can't
If the last number is a double-digit number, i.e. ,25 instead of 2, then the that second part (,[0-9\s]+)* would be satisfied because it found at least one number and [0-9]$ would match the next number which is 5 (https://regex101.com/r/0XbHsw/1)
Adding ? for that last part would solve the problem: [0-9\s]+(,[0-9\s]+)*[0-9]?$
I wanted to know how I could split a string based on the first character that is not 0, e.g.
$ID = ABC-000000160810;
I want to split the id so it looks like this:
$split_ID = 160810;
I tried to just get the last 6 digits, however the problem was that the 6 digits might not always be consistent, so just need to split based on the first non-zero. What is the easiest way to achieve this?
Thanks.
Here's a way using a regular expression:
$id = 'ABC-000000160810';
preg_match('/-0*([1-9][0-9]*)/', $id, $matches);
$split_id = $matches[1];
You can use ltrim if you only want to remove leading zeroes.
$ID = ABC-000000160810;
$split_ID = ltrim($str, '0');
Use ltrim to remove leading characters.
$id = 'ABC-00001234';
$numeric = ltrim(mb_substr($id, mb_strpos($id, '-') + 1), '0');
echo $numeric; // 1234
The above requires the mbstring extension to be enabled. If you encounter an error, either enable the extension or use the non-multibyte functions substr and strpos. Probably you should get in the habit of using the mb_ string functions.
This should also work:
const CHAR_MASK = 'a..zA..Z-0';
$id = 'ABC-00001234';
$numeric = ltrim($id, CHAR_MASK);
echo $numeric; // 1234
For your example "ABC-00000016081" you might use a regex that would match the first part up until you encounter not a zero and then use \K to not include the previously consumed characters in the final match.
[^-]+-0+\K[1-9][0-9]+
[^-]+ Match not a - one or more times using a negated character class
- Match literally
0+ Match one or more times a zero (If you want your match without leading zeroes you could use 0*)
\K Resets the starting point of the reported match
[1-9][0-9]* Match your value starting with a digit 1 -9
Test
You can substr off the ABC part and multiply with 1 to make it a number.
$ID = "ABC-000000160810";
Echo substr($ID, 4)*1;
I've got a string:
$string = "Something here 2014 another text here";
I need to detect position of the first 4 digits number that begins with "20".
So the result of the example would be 15th character of the $string.
Since you have commented with code you tried, I now feel comfortable answering your question properly :) Thank you for trying first!
Your attempt:
preg_match('/20\d\d/', "Something here 2014 another text here",
$matches, PREG_OFFSET_CAPTURE);
... is absolutely correct, however as you correctly pointed out, it would also match 20140 (and indeed 12014 would match too).
To fix this behaviour, you can add word boundaries - because numbers count as word characters. Your regex becomes:
'/\b20\d\d\b/'
This will ensure that there are no numbers (or letters, for that matter) immediately before or after your target four-digit number :)
What about...
$needle = "20";
$pos = strpos($string , $needle);
EDIT:
as requested, a way to get the string from this
$date = substr ($string , $pos , 4 ]);
There is a method to know which characters does not match a preg_match function?
For example:
preg_match('/^[a-z]*$/i', 'Hello World!');
Is there some function to know the incorrect char, in this case spance and "!"?
Thanks for your replies, but the problem in your examples is you don't indicate the begin and the end of the string. Your examples works with string contained in another one and not with the string that is exactly like I defined in the pattern.
For example, if I had to validate the italian fiscal code of a subject, composed by a string formatted like this:
XXX XXX YY X YY X YYY X (X = letter, Y = number - without spaces)
which pattern is:
'/^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$/i'
I must validate the string that match exactly what I defined in the pattern.
If I use your code and I wrong 1 (only 1) character, the whole string was returned as error.
http://eval.in/9178
The problem of the reverse pattern occurs in a complex pattern, where are inserted the AND or the OR.
What I want to know is why the preg_match fails and not only if it fails or not.
Have you tried something like this?
$nonMatchingCharacters = preg_replace('/[a-z]/', '', $wholeString);
That should strip out the 'legal' characters, leaving only the ones that you want to mention in your validation error message.
You could also do other treatments like...
$nonMatchingCharactersArray = array_unique(explode('', $nonMatchingCharacters));
...if you want an array of unique, non-matching characters, and not just a string with bits stripped out of it.
That will indicate you the space and !
preg_match_all('/[^a-z]/i', 'Hello World!', $matches);
var_dump($matches);
http://eval.in/9132
Just remove everything that matches with preg_replace, then split into an array what remains.
<?php
$str = preg_replace('/([0-9]{2}[a-z]*)/i', '', '03Hello 02World!');
$characters = str_split($str);
var_dump($characters);
http://eval.in/9152