how to validate the first four character in string using php? - php

I want to make script that only accept the ff;
1st, 2nd, and 3rd character from a word/string/paragraph == ABC;
4th
character from a word/string/paragraph == asterisk(*);
5th to 20th from accept only a numeric integer...
<?php
$subject = "das*3445465656343";
$pattern = '/^[ABCabc]{3}$/';
preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
?>

This should work for you:
Just use this regex:
$pattern = "/^abc\*\d{16}$/i";
Explanation:
^ assert position at start of a line
abc matches the characters abc literally (case insensitive)
\* matches the character * literally
\d{16} match a digit [0-9]
Quantifier: {16} Exactly 16 times
$ assert position at end of a line
i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])
Demo

Check this regex: (?=^abc\*\d{16}$).+
DEMO

Related

Looking for regex to obfuscate email to t*#w***.de

I have the following:
$pattern = "/^([\w_]{1})(.+)([\w_]{1}#)/u";
$replacement = "$1*$3***$4";
$email = "testa#weste.de";
echo "obfuscated: ".preg_replace($pattern, $replacement, $email).RT;
The result is: t*a#***weste.de
But I would like to have: t*#w***.de
How to grab the letter after the # and not before. And how does it work with the .de part?
For the replacement in the example data, you might use a match with \K to forget what is matched after the first character and keep it.
To keep the first character after the # sign, you can use a capture group and use that in the replacement.
^\w\K[^\s#]+#(\w)[^\s.#]+
^ Start of string
\w Match a single word char (That will also match _)
\K Forget what is matched so far
[^\s#]+ Match 1+ chars other than # or a whitespace char
# Match the # char
(\w) Capture group 1, match a word char (to keep)
[^\s.#]+ Match 1+ chars other than #, a whitespace char or dot
Regex demo | Php demo
In the replacement use a single capture group *#$1***
$email = "testa#weste.de";
$pattern = "/^\w\K[^\s#]+#(\w)[^\s.#]+/";
$replacement = "*#$1***";
echo preg_replace($pattern, $replacement, $email);
Output
t*#w***.de
You can make the pattern as specific as you would like. If there should for example be a dot followed by at least 2 chars a-z at the end of the string, and you don't want to stop matching at the first dot after the #
^\w\K[^\s#]+#(\w)[^\s#]+(?=\.[a-z]{2,}$)
Regex demo
I found this way to do it:
$email = 'someemail#domain.com'
[$firstPart, $lastPart] = explode('#', $email);
$maskedEmail = str_replace(substr($firstPart, 0, 7), str_repeat('*', 7), $email);
Uses PHP native functions and works just fine!

Extract time within parentheses using PHP

This is my first time using the trim function and I want to get the Time excluding the open and close parenthesis of my string. Can you give me hints and suggestions on how to do this?
$string = "Updated by Carewina Almonte (04/02/2018 21:58:32)";
echo trim($string, "Updated by Carewina Almonte (04/02/2018");
exit();
In php, You can do get this and this works if and only if date and time always appears at the end of string -
$string = "Updated by Carewina Almonte (04/02/2018 21:58:32)";
$time = substr($string,-9,8);
echo $time;
$string = "Updated by Carewina Almonte (04/02/2018 21:58:32)";
if(preg_match("/\d{2}:\d{2}:\d{2}/", $string , $match))
{
echo $match[0];
}
Regular expression should be used in this case.
You can use preg_match for this task:
$str = 'Updated by Carewina Almonte (04/02/2018 21:58:32)';
preg_match('/(?<=\(\d{2}\/\d{2}\/\d{4} ).*(?=\))/', $str, $match);
echo $match[0];
Breakdown:
Positive Lookbehind (?<=\(). Assert that the Regex below matches:
\( matches the character ( literally (case sensitive)
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\d{2} matches a digit (equal to [0-9])
{2} Quantifier — Matches exactly 2 times
\/ matches the character / literally (case sensitive)
Positive Lookahead (?=\)). Assert that the Regex below matches:
\) matches the character ) literally (case sensitive)
For you example string you might match what is between parenthesis using \(\K[^)]+(?=\)).
This will match an opening parenthesis \( and then use \K to reset the starting point of the reported match.
After that match NOT a closing parenthesis one or more times [^)]+ and a positive lookahead to assert that what follows is a closing parenthesis (?=\)).
Then you could create a DateTime using or use DateTime::createFromFormat using $matches[0] and extract the time:
$re = '/\(\K[^)]+(?=\))/';
$str = 'Updated by Carewina Almonte (04/02/2018 21:58:32)';
preg_match($re, $str, $matches);
$dateTime = new DateTime($matches[0]);
if ($dateTime !== false) {
echo $dateTime->format('H:i:s');
}
Test

split string in numbers and text but accept text with a single digit inside

Let's say I want to split this string in two variables:
$string = "levis 501";
I will use
preg_match('/\d+/', $string, $num);
preg_match('/\D+/', $string, $text);
but then let's say I want to split this one in two
$string = "levis 5° 501";
as $text = "levis 5°"; and $num = "501";
So my guess is I should add a rule to the preg_match('/\d+/', $string, $num); that looks for numbers only at the END of the string and I want it to be between 2 and 3 digits.
But also the $text match now has one number inside...
How would you do it?
To slit a string in two parts, use any of the following:
preg_match('~^(.*?)\s*(\d+)\D*$~s', $s, $matches);
This regex matches:
^ - the start of the string
(.*?) - Group 1 capturing any one or more characters, as few as possible (as *? is a "lazy" quantifier) up to...
\s* - zero or more whitespace symbols
(\d+) - Group 2 capturing 1 or more digits
\D* - zero or more characters other than digit (it is the opposite shorthand character class to \d)
$ - end of string.
The ~s modifier is a DOTALL one forcing the . to match any character, even a newline, that it does not match without this modifier.
Or
preg_split('~\s*(?=\s*\d+\D*$)~', $s);
This \s*(?=\s*\d+\D*$) pattern:
\s* - zero or more whitespaces, but only if followed by...
(?=\s*\d+\D*$) - zero or more whitespaces followed with 1+ digits followed with 0+ characters other than digits followed with end of string.
The (?=...) construct is a positive lookahead that does not consume characters and just checks if the pattern inside matches and if yes, returns "true", and if not, no match occurs.
See IDEONE demo:
$s = "levis 5° 501";
preg_match('~^(.*?)\s*(\d+)\D*$~s', $s, $matches);
print_r($matches[1] . ": ". $matches[2]. PHP_EOL);
print_r(preg_split('~\s*(?=\s*\d+\D*$)~', $s, 2));

change line to bold, if it ends with a colon, and only contains one word

How do I change the word to bold, if there is only one word on a line with a colon at the end?
data comes from at text field in mysql database, and code is php
You can capture the word and substitute surrounded by <b>
^(\w+):$
Live demo
Sample code:
$re = "/^(\\w+):$/m";
$str = "abc:\nabc\nabc:xyz\n";
$subst = '<b>$1</b>';
$result = preg_replace($re, $subst, $str);
Pattern explanation:
^ the beginning of the string
( group and capture to \1:
\w+ word characters (a-z, A-Z, 0-9, _) (1 or more times)
) end of \1
: ':'
$ before an optional \n, and the end of the string
Use this:
$replaced = preg_replace('~^\w+:$~', '<b>$0</b>', $yourstring);
Explanation
The ^ anchor asserts that we are at the beginning of the string
The \w+ matches one or more word chars
: matches the colon
The $ anchor asserts that we are at the end of the string
We replace with <b>, the overall match (referenced by $0) and </b>

Regular expression to check if two first words are same

For example:
$s1 = "Test Test the rest of string"
$s2 = "Test the rest of string"
I would like to match positively $s1 but not $s2, because first word in $s1 is the same as second. Word 'Test' is example, regular expression should work on any words.
if(preg_match('/^(\w+)\s+\1\b/',$input)) {
// $input has same first two words.
}
Explanation:
^ : Start anchor
( : Start of capturing group
\w+ : A word
) : End of capturing group
\s+ : One or more whitespace
\1 : Back reference to the first word
\b : Word boundary
~^(\w+)\s+\1(?:\W|$)~
~^(\pL+)\s+\1(?:\PL|$)~u // unicode variant
\1 is a back reference to the first capturing group.
This does not cause Test Testx to return true.
$string = "Test Test";
preg_match('/^(\w+)\s+\1(\b|$)/', $string);
Not working everywhere, see the comments...
^([^\b]+)\b\1\b
^(\B+)\b\1\b
Gets the first word, and matches if the same word is repeated again after a word boundary.

Categories