PHP regex preg_replace function Joomla! plugin - php

I want to create plugin that finds and replaces phone numbers with a linked number for mobile. This is a php function that I have written for Joomla to use to replace a phone number...
protected function clickToCall(&$text, &$params){
// phone number pattern...
$pattern = '~(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}~';
//replacement pattern...
$replacement = '$1$2';
//use preg_replace to actually replace the pattern
$text = preg_replace($pattern, $replacement, $text);
//return the new value
return true;
}
Right now the function finds the pattern and just replaces it with an empty link. How can insert the phone number found by regex into a link?

The problem is that you are using $1 and $2 backreferences that refer to Group 1 (i.e. substring captured with (\+0?1\s)?) and non-existent Group 2 (thus, it is an empty string) rather than to the whole match (that can be referred to with the help of $0 or \0).
Here is a fix:
$text = 'Phone +1 (234) 345 6543 to obtain a free copy.';
$pattern = '~(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}~';
$replacement = '$0';
echo $text = preg_replace($pattern, $replacement, $text);
See IDEONE demo
See more about Back references in PHP Manual.

Related

PHP REGEX find & replace patterns

Trying to construct a regex that will locate a pattern of ANY character followed by double quotes
This regex locates each occurrence properly
(\S"")
Given the example below
$string='"WEINSTEIN","ANTONIA \"TOBY"","STILES","HOOPER \"PETER"","HENDERSON",';
$pattern = '(\S"")';
$replacement = '\\""';
$result=preg_replace($pattern, $replacement, $string);
My result turns out to be
"WEINSTEIN","ANTONIA \"TOB\"","STILES","HOOPER \"PETE\"","HENDERSON"
But I am seeking
"WEINSTEIN","ANTONIA \"TOBY\"","STILES","HOOPER \"PETER\"","HENDERSON"
I understand the replacement is removing/replacing the whole match, but how can I remove all but the first letter rather than completely replacing it?
You can change your pattern to use a positive lookbehind instead so that it doesn't capture the non-space character:
$string='"WEINSTEIN","ANTONIA \"TOBY"","STILES","HOOPER \"PETER"","HENDERSON",';
$pattern = '/(?<=\S)""/';
$replacement = '\\""';
$result=preg_replace($pattern, $replacement, $string);
echo $result;
Output
"WEINSTEIN","ANTONIA \"TOBY\"","STILES","HOOPER \"PETER\"","HENDERSON",
Demo on 3v4l.org

Php select from string

Hi I'm new to php and I need a little help
I need to change the text that is between ** in php string and put it between html tag
$text = "this is an *example*";
But I really don't know how and i need help
personally I would use explode, you can then piece the sentence back together if the example appears in the middle of a sentence
<?php
$text = "this is an *example*";
$pieces = explode("*", $text);
echo $pieces[0];
?>
Edit:
Since you're looking for what basically amounts to custom BB Code use this
$text = "this is an *example*";
$find = '~[\*](.*?)[\*]~s';
$replace = '<span style="color: green">$1</span>';
echo preg_replace($find,$replace,$text);
You can add this to a function and have it parse any text that gets passed to it, you can also make the find and replace variables into arrays and add more codes to it
You really should use a DOM parser for things like this, but if you can guaratee it will always be the * character you can use some regex:
$text = "this is an *example*";
$regex = '/(?<=\*)(.*?)(?=\*)/';
$replacement = 'ostrich';
$new_text = preg_replace($regex, $replacement, $text);
echo $new_text;
Returns
this is an *ostrich*
Here is how the regex works:
Positive Lookbehind (?<=\*)
\* matches the character * literally (case sensitive)
1st Capturing Group (.*?)
.*? matches any character (except for line terminators)
*? Quantifier — Matches between zero and unlimited times, as few times as possible, expanding as needed (lazy)
Positive Lookahead (?=\*)
\* matches the character * literally (case sensitive)
This regex essentially starts and ends by looking at what is ahead of and behind the search character you specified and leaves those characters intact during the replacement with preg_replace().

Issue with regular expression for identifying encrypted ids from string

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

preg_replace only substring before defined char

I'm trying to replace chars not [A-Z] and before the # inside a string. So this
AreplacehereZ#domain.tld
needs to become:
A***********Z#domain.tld
I tried with:
$string = 'AreplacehereZ#domain.tld';
$pattern = '/(?<!#)[^A-Z#\.]/';
$replacement = '*';
$replace = preg_replace($pattern, $replacement, $tring);
but the result is
'A***********Z#d*****.***'
So I can't find the way how to avoid the replacement of #domain.tld by only using preg_replace().
domain.tld can be anything so I can't use (?<!#domain.tld) in the $pattern var.
You can just assert that from the current position, match [^A-Z], then make sure you can consume any number of characters but still hit the #:
$pattern = '/[^A-Z](?=[^#]*#)/';
Produces:
A***********Z#domain.tld

How to extract a collection of numbers from a string?

I need to extract a project number out of a string. If the project number was fixed it would have been easy, however it can be either P.XXXXX, P XXXXX or PXXXXX.
Is there a simple function like preg_match that I could use? If so, what would my regular expression be?
There is indeed - if this is part of a larger string e.g. "The project (P.12345) is nearly done", you can use:
preg_match('/P[. ]?(\d{5})/',$str,$match);
$pnumber = $match[1];
Otherwise, if the string will always just be the P.12345 string, you can use:
preg_match('/\d{5}$/',$str,$match);
$pnumber = $match[0];
Though you may prefer the more explicit match of the top example.
Try this:
if (preg_match('#P[. ]?(\d{5})#', $project_number, $matches) {
$project_version = $matches[1];
}
Debuggex Demo
You said that project number is 4 of 5 digit length, so:
preg_match('/P[. ]?(\d{4,5})/', $tring, $m);
$project_number = $m[1];
Assuming you want to extract the XXXXX from the string and XXXXX are all integers, you can use the following.
preg_replace("/[^0-9]/", "", $string);
You can use the ^ or caret character inside square brackets to negate the expression. So in this instance it will replace anything that isn't a number with nothing.
I would use this kind of regex : /.*P[ .]?(\d+).*/
Here is a few test lines :
$string = 'This is the P123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
$string = 'This is the P.123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
$string = 'This is the P 123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
use explode() function to split those

Categories