Issue with regular expression for identifying encrypted ids from string - php

I want to convert certain patterns into links and it works fine as far as normal user ids are considered.But now i want to do the same for encrypted ids as well.
Below is my code:(works)
$text = "hi how are you guys???... ##[Sam Thomas:10181] ##[Jack Daniel:11074] ##[Paul Walker:11043] ";
$pattern = "/##\[([^:]*):(\d*)\]/";
$matches = array();
preg_match_all($pattern, $text, $matches);
$output = preg_replace($pattern, "$1", $text);
Now i need to do link the text like:
"hi how are you guys???... ##[Sam Thomas:ZGNjAmD9ac3K] ##[Jack Daniel:ZGNjAmD9ac3K] ##[Paul Walker:ZGNjAmD9ac3K] ";
But this encrypted is not identified by above regular expression...

##\[([^:]*):(.*?)\]
^^
Try this.See demo.Just change \d* to .*? to accept anything or \w* to accept only numbers and letters.or [^\]]* or [0-9a-zA-Z] as well.
https://regex101.com/r/vD5iH9/52

Change your regex to accept numbers and letters as well.
Something like this -
##\[([^:]*):([0-9a-zA-Z]*)\]
^^^^^^^^^^^ Replaced \d
Demo

Related

Suggestion about search coincidences in string with PHP using REGEX

I am trying to search this coincidence in a string:
1. I need to take only numbers after the chracter '#' as long as this coincidence has not spaces, for example:
String = 'This is a test #VVC345RR, text, and more text 12345';
I want to take only this from my string -> 345.
My example:
$s = '\"access_token=103782364732640461|2. myemail#domain1.com ZmElnDTiZlkgXbT8e3 #DD234 4Jrw__.3600.1281891600-10000186237005';
$matches = array();
$s = preg_match('/#([0-9]+)/', $s, $matches);
print_r($matches);
This only works when I have one # and numbers.
Thanks!
Maybe:
#\D*\K(\d+)
Accomplishes what you want?
This will look for an #, any non-numbers, and then capture the numbers. The \K ignores the early match.
https://regex101.com/r/gNTccx/1/
I'm unclear what you mean by has not spaces, there are no spaces in the example string.

PHP exploding url from text, possible?

i need to explode youtube url from this line:
[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]
It is possible? I need to delete [embed] & [/embed].
preg_match is what you need.
<?php
$str = "[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]";
preg_match("/\[embed\](.*)\[\/embed\]/", $str, $matches);
echo $matches[1]; //https://www.youtube.com/watch?v=L3HQMbQAWRc
$string = '[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]';
$string = str_replace(['[embed]', '[/embed]'], '', $string);
See str_replace
why not use str_replace? :) Quick & Easy
http://php.net/manual/de/function.str-replace.php
Just for good measure, you can also use positive lookbehind's and lookahead's in your regular expressions:
(?<=\[embed\])(.*)(?=\[\/embed\])
You'd use it like this:
$string = "[embed]https://www.youtube.com/watch?v=L3HQMbQAWRc[/embed]";
$pattern = '/(?<=\[embed\])(.*)(?=\[\/embed\])/';
preg_match($pattern, $string, $matches);
echo $match[1];
Here is an explanation of the regex:
(?<=\[embed\]) is a Positive Lookbehind - matches something that follows something else.
(.*) is a Capturing Group - . matches any character (except a newline) with the Quantifier: * which provides matches between zero and unlimited times, as many times as possible. This is what is matched between the groups prior to and after. This are the droids you're looking for.
(?=\[\/embed\]) is a Positive Lookahead - matches things that come before it.

preg_replace() pattern to remove brackets and content in php

I want to remove the brackets with its content using preg_replace(), but i am unable to use a lazy(non-greedy) in the pattern since the end bracket is the end character, the text in between the brackets is always a random character length and can contain numbers, underscores, and hyphens.
code-
$array = array(
"Text i want to keep (txt to remove)",
"Random txt (some more random txt)",
"Keep this (remove)",
"I like bananas (txt)"
);
$pattern = "#pattern#";
foreach($array as $new_txt){
$new_outputs .= preg_replace($pattern, '', $new_txt)."\n";
}
echo $new_outputs;
Wanted output-
Text i want to keep
Random txt
Keep this
I like bananas
I do not use regular expressions much and couldn't find anything to solve my problem.
The following regular expression should do it:
$pattern = '#\(.*?\)#';
.*? is a non-greedy match of anything.
$new_outputs .= preg_replace('#\([^\)]*\)$#','',$new_txt);
This might help you:
$pattern = "/\([^)]*\)+/";
foreach($array as $new_txt){
$new_outputs .= preg_replace($pattern, '', $new_txt)."\n";
}

preg_replace() seems to remove entire word instead of part of it

I'm trying to match a certain word and replace part of the word with certain text but leave the rest of the word intact. It is my understanding that adding parentheses to part of the regex pattern means that the pattern match within the parentheses gets replaced when you use preg_replace()
for testing purposes I used:
$text = 'batman';
echo $new_text = preg_replace('#(bat)man#', 'aqua', $text);
I only want 'bat' to be replaced by 'aqua' to get 'aquaman'. Instead, $new_text echoes 'aqua', leaving out the 'man' part.
preg_replace replaces all the string matched by regular expression
$text = 'batman';
echo $new_text = preg_replace('#bat(man)#', 'aqua\\1', $text);
Capture man instead and append it to your aqua prefix
Another way of doing that is to use assertions:
$text = 'batman';
echo $new_text = preg_replace('#bat(?=man)#', 'aqua', $text);
I would not use preg_* functions for this and just do str_replace() DOCs:
echo str_replace('batman', 'aquaman', $text);
This is simpler as a regex is not really needed in this case. Otherwise it would be with a regular expression:
echo $new_text = preg_replace('#bat(man)#', 'aqua\\1', $text);
This will substitute your man in after aqua when replacing the entire search phrase. preg_replace DOCs replaces the entire matching portion of the pattern.
The way you're trying to do it, it would be more like:
preg_replace('#bat(man)#', 'aqua$1', $text);
I'd using positive lookahead:
preg_replace('/bat(?=man)/', 'aqua', $text)
Demo here: http://ideone.com/G9F4q
The brackets are creating a capturing group, that means you can access the part matched by this group using \1.
you can do either what zerkms suggested or use a lookahead that does just check but not match.
$text = 'batman';
echo $new_text = preg_replace('#bat(?=man)#', 'aqua', $text);
This will match "bat" but only if it is followed by "man", and only "bat" is replaced.

how could I combine these regex rules?

I'm detecting #replies in a Twitter stream with the following PHP code using regexes.
$text = preg_replace('!^#([A-Za-z0-9_]+)!', '#$1', $text);
$text = preg_replace('! #([A-Za-z0-9_]+)!', ' #$1', $text);
How can I best combine these two rules without false flagging email#domain.com as a reply?
OK, on a second thought, not flagging whatever#email means that the previous element has to be a "non-word" item, because any other element that could be contained in a word could be signaled as an email, so it would lead:
!(^|\W)#([A-Za-z0-9_]+)!
but then you have to use $2 instead of $1.
Since the ^ does not have to stand at the beginning of the RE, you can use grouping and | to combine those REs.
If you don't want re-insert the whitespace you captured, you have to use "positive lookbehind":
$text = preg_replace('/(?<=^|\s)#(\w+)/',
'#$1', $text);
or "negative lookbehind":
$text = preg_replace('/(?<!\S)#(\w+)/',
'#$1', $text);
...whichever you find easier to understand.
Here's how I'd do the combination
$text = preg_replace('!(^| )#([A-Za-z0-9_]+)!', '$1#$2', $text);
$text = preg_replace('/(^|\W)#(\w+)/', '#$2', $text);
preg_replace('%(?<!\S)#([A-Za-z0-9_]+)%', '#$1', $text);
(?<!\S) is loosely translated to "no preceding non-whitespace character". Sort of a double-negation, but also works at the start of the string/line.
This won't consume any preceding character, won't use any capturing group, and won't match strings such as "foo-#host.com", which is a valid e-mail address.
Tested:
Input = 'foo bar baz-#qux.com bee #def goo#doo #woo'
Output = 'foo bar baz-#qux.com bee #def goo#doo #woo'
Hu, guys, don't push too far... Here it is :
!^\s*#([A-Za-z0-9_]+)!
I think you can use alternation,: so look for the beginning of a string or a space
'!(?:^|\s)#([A-Za-z0-9_]+)!'

Categories