I am trying to replace some text if it isn't preceded with a dot (.), but my function seems to result include an unexpected slash ...
<?php
$test="function insertXYZ(e){e.insertXYZ()};";
$search="insertXYZ(";
$replace="zzzz(";
$search=str_replace("(", '\(', $search);
//echo $search."\n\n";
$pattern = '\b' . $search;
$replaceException="999";
$test=preg_replace('/' . "\.".$pattern . '/', "$replaceException", $test);
$test=preg_replace('/' . $pattern . '/', $replace, $test);
$test=preg_replace('/' . $replaceException . '/', ".$search", $test);
echo $test;
?>
A sample of this code can be found at http://sandbox.onlinephpfunctions.com/code/24cab4eece20d22a11dd887da44d63e393b51aa9
which outputs...
function zzzz(e){e.insertXYZ\()};
^
but I want the output to read...
function zzzz(e){e.insertXYZ()};
^
Where am I going wrong?
It's because in this line, you're adding the backslash and then never remove it
$search=str_replace("(", '\(', $search);
You could change your code to the following so that you don't need to manually escape this bracket.
// $search=str_replace("(", '\(', $search); <-- Removed
$pattern = '\b' . preg_quote($search);
However, you could get the same output with much less code
$testString = "function insertXYZ(e){e.insertXYZ()};";
$regex = "/[^.](insertXYZ)/s";
echo(preg_replace($regex, " zzzz", $testString));
[^.] - Character group looking where there's NOT a dot character
(insertXYZ) - matches 'insertXYZ' exactly (case sensitive)
/s - Single line modifier so there's no need to escape the dot character
Related
I am investigating, but I am not able to find the solution to this.
The idea is to replace the characters $_ from a string with something else.
If you remove the dollar sign from the $search variable, it kind of works (but not in a desirable way).
It is not working because the dollar sign is a special character, but I cannot find how to scape it.
This is what I have:
$search = '$_'; // replace to '_' OR '[$_]' it returs "$1" instead of "1"
$replace = 1;
$regex = '#".*?"(*SKIP)(*FAIL)|\b' . $search . '\b#s';
$fullInput = '"$_" $_';
$r = preg_replace([$regex], $replace, $fullInput);
echo $r . PHP_EOL;
// Output with current code : "$_" $_
// Output with '_' or '[$_]': "$_" $1
//
// Expected result: "$_" 1
To have into account, if the text is between quotes, it should not be replaced.
You may use this regex for search:
"[^\\"]*(?:\\.|[^\\"]*)*"(*SKIP)(*F)|\$_
and replace it with [$0]
Pattern before | matches a double quoted string allowing an escaped quote in between. Pattern after | matches $_.
RegEx Demo
RegEx Details:
"[^\\"]*(?:\\.|[^\\"]*)*": Match a double quoted string. We allow escaped characters in this match.
(*SKIP)(*F): Skip and fail this match
|: OR
\$_: Match literal text $_
Code:
$search = '$_';
$replace = '[$0]';
$regex = '/"[^\\"]*(?:\\.|[^\\"]*)*"(*SKIP)(*F)|' . preg_quote($search, '/') . '/';
$fullInput = '"$_" $_';
$r = preg_replace($regex, $replace, $fullInput);
echo $r . PHP_EOL;
Output:
"$_" [$_]
I am trying to replace all occurrences of '/ /' in a string with '/'. I can't seem to find the right regex expression to match the string to replace, however.
Currently, I have preg_replace('/\/\s\//', '/', $string); but this does not replace any occurrences of '/ /'.
To be clear, I would like to match any occurrences of a forward slash followed by whitespace followed by a forward slash. It seems that the last forward slash messes things up. I have also tried str_replace(), but to no avail.
EDIT:
The regex expression works correctly if I run it on a string like so:
echo(preg_replace('/\/\s?\//m', '/', ".... . -.-- / / .... ---")); and I get the output: .... . -.-- / .... ---. But when I run it like this:
$morse = preg_replace('/\/\s?\//m', '/', $morse); The replacement does not work. For the record, the ouput of echo($morse) before preg_replace is .... . -.-- / / .... --- and after it is the exact same. I have no idea what could be causing this, some sort of weird encoding in the $morse variable string?
Please help, this is driving me crazy. Thanks in advance!
The regex pattern you have written is correct and it will replace if the / / occurrence is found. I updated your pattern to /\/\s?\//m. You can try the following way.
$re = '/\/\s?\//m';
$str = 'test string // test string / /';
$subst = '/';
$result = preg_replace($re, $subst, $str);
echo "The result of the substitution is ".$result;
The use of other delimiters would simplify things enormously here:
$regex = '~/\s+/~';
$replacement = '/';
$string = preg_replace($regex, $replacement, $original_string);
Note, that your original string is left untouched.
Looking for a php regex that will allow me to separate out certain characters from words (if they're sticking to the left or right of the word, or even anywhere within the word).
For example,
hello. -> hello .
.hello -> . hello
hello.hello -> hello . hello
I have the below code but it won't work for all cases. Please note that $value could be '.', '?', or any character.
$regex = "/(?<=\S)\\" . $value . "|\\" . $value . "(?=\S)/";
$this->str = preg_replace_callback($regex, function($word) {
return ' ' . $word[0];
}, $this->str);
Also, please help with specifying the part where I can turn on (or off) the 3rd condition.
[UPDATE]
I think there might be confusion about exact requirements. Let me try to be more specific. I want a regex which will help me seperate out certain characters which are either at the end or the beginning of a group of text. What is group of text? Group of text could be any length (>=1) and contain any characters however it must begin with a-z or 0-9. Again, would be nice if this aspect would be highlighted in solution so that if we want group of text to begin&end with more characters (not just a-z or 0-9) it's possible.
$character = '.', string is ".hello.world." => ". hello.world ."
$character = '.', string is ".1ello.worl2." => ". 1ello.worl2 ."
$character = '.', string is ".?1ello.worl2." => ".?1ello.worl2 ."
$character = '.', string is "4/5.5" => "4/5.5"
$character = '.', string is "4.?1+/5" => "4.?1+/5"
$character = '.', string is ".4/5.5." => ". 4/5.5 ."
$character = '/', string is ".hello?.world/" => ".hello?.world /"
$character = '/', string is ".hello?.worl9/" => ".hello?.worl9 /"
Hope, its more clear now.
You can use 3 alternatives each captured into its own capture group, and use a preg_replace_callback to apply the corresponding replacement:
$wrd = ".";
$re = '~(?<=\S)(' . preg_quote($wrd) . ')(?=\S)|(?<=\S)(' . preg_quote($wrd) . ')|(' . preg_quote($wrd) . ')(?=\S)~';
$str = "hello.\n.hello\nhello.hello";
$result = preg_replace_callback($re, function($m) {
if (!empty($m[1])) {
return " " . $m[1] . " ";
} else if (!empty($m[2])) {
return " " . $m[2];
} else return $m[3] . " ";
}, $str);
echo $result;
See the IDEONE demo
The regex will be
(?<=\S)(\.)(?=\S)|(?<=\S)(\.)|(\.)(?=\S)
| 1| | 2| | 3|
See regex demo
The first group is your Case 3 (hello.hello -> hello . hello), the second group is your Case 1 (hello. -> hello .) and the third group singals your Case 2 (.hello -> . hello).
UPDATE (handling exceptions)
If you have exceptions, you can add more capturing groups. E.g., you want to protect the dot in float numbers. Add a (\d\.\d) alternative, and check inside the callback function if it is not empty. If not, just restore it with return $m[n]:
$wrd = ".";
$re = '~(\d\.\d)|(?<=\S)(' . preg_quote($wrd) . ')(?=\S)|(?<=\S)(' . preg_quote($wrd) . ')|(' . preg_quote($wrd) . ')(?=\S)~';
$str = "hello.\n.hello\nhello.hello\nhello. 3.5/5\nhello.3\na./b";
$result = preg_replace_callback($re, function($m) {
if ( !empty($m[1])) { // The dot as a decimal separator
return $m[1]; // No space is inserted
}
else if (!empty($m[2])) { // A special char is enclosed with non-spaces
return " " . $m[2] . " "; // Add spaces around
} else if (!empty($m[3])) { // A special char is enclosed with non-spaces
return " " . $m[3]; // Add a space before the special char
} else return $m[4] . " "; // A special char is followed with a non-space, add a space on the right
}, $str);
echo $result;
See an updated code demo
Another code demo - based on matching locations before and after the . that are not enclosed with spaces (and protecting a float value) (based on #bobblebubble's solution (deleted)):
$wrd = ".";
$re = '~(\d\.\d)|(?<!\s)(?=' . preg_quote($wrd) . ')|(?<=' . preg_quote($wrd) . ')(?!\s)~';
$str = "hello.\n.hello\nhello.hello\nhello. 3.5/5\nhello.3\na./b";
$result = preg_replace_callback($re, function($m) {
if ( !empty($m[1])) { // The dot as a decimal separator
return $m[1]; // No space is inserted
}
else return " "; // Just insert a space
}, $str);
echo $result;
SUMMARY:
You cannot use \b since your . / ? etc. can appear in mixed "word" and "non-word" contexts
You need to use capturing and preg_replace_callback since there are different replacement schemes
You can use a regex based on word boundaries.
\b(?=\.(?!\S))|(?<=(?<!\S)\.)\b
Would match the boundary (zero-width) between a word and a literal dot if not followed by a non-whitespace \S or not preceded by a non-whitespace using lookarounds to check.
See demo at regex101. Use in a PHP function with value parameter and replace with space.
// $v = character
function my_func($str, $v=".")
{
$v = preg_quote($v, '/');
return preg_replace('/\b(?='.$v.'(?!\S))|(?<=(?<!\S)'.$v.')\b/', " ", $str);
}
PHP demo at eval.in
From what I understand the . can be any non-word character. If that's the case, try this:
$patron = '/(\W+)/';
$this->str = trim(preg_replace($patron, ' $1 ', $this->str));
(\s?[.]\s?)
If you use the above regex, you can simply replace all the matches with " . "
How it works:
I used \s? to capture a leading and trailing whitespace, if there is any.
[.] is a char class, so you should add all of the "certain characters" you want to find.
A regex that catches the first 2 conditions and never the third is (\s[.]\s?|\s?[.]\s). (Again, you'll need to replace the capture with " . ", and also add your "certain characters" to the char classes.)
You can then choose which regex you will use.
Trying to remove the hyphens which come before start of the alphabet and after end of a alphabet, but not to lose the hyphens in between.
Example
this the string i have
---this-is-my-page--
output: this-is-my-page
Note( no of hyphen are different on each request, it may be many in numbers)
2. Example
how to do this,
---this-is-page---
i need to replace the hyphen which is in between string with empty space. but not to loose to the hyphens in start and end.
Use trim function it will work for any number of -(hyphen) at start or end of your string,
$str = "---this-is-my-page---";
echo $str = trim($str,"-");
Edit:
And than use str_replace,
$str = str_replace("-"," ",$str);
DEMO.
Use trim($string, $trimCharacters):
trim — Strip whitespace (or other characters) from the beginning and end of a string
<?php
$str = '---this-is-my-page---';
var_dump( trim($str, '-') ); //string(15) "this-is-my-page"
?>
DEMO
If you only want to replace the hyphens inside the string (and not in the start/end) you can use regex:
/^(-+)(.*?)(-+)$/
..and replace it with (first group)(second group with hyphens replaced)(third group).
In code:
<?php
$str = '---this-is-my-page---';
$str = preg_replace_callback('/^(-+)(.*?)(-+)$/', function($matches) {
return $matches[1] . str_replace('-', ' ', $matches[2]) . $matches[3];
}, $str);
var_dump( $str ); //string(21) "---this is my page---"
?>
DEMO
echo trim( "---this-is-my-page---","-");
trim removes a character at the and and begin
Hello i have a regex which accepts mostly every character including specials.And i have set
it to accept minimum 8 and maximum 30 characters.
Everything is right for minimum but it's not working for maximum.
If string is more than 30 or any length. The result is true.
The pattern is here:
$pattern = '/[A-Za-z0-9' . preg_quote( '.%^&()$##!/-+/', '/') . ']{8,30}/';
The whole testing code is:
$pattern = '/^[A-Za-z0-9' . preg_quote( '.%^&()$##!/-+/', '/') . ']{8,30}$/';
if(preg_match($pattern, $pass))
{
echo '<br>true';
}
else
{
echo '<br>false';
}
?>
This will match any string up to 30 characters within the string. You need to include the start and end of the string:
$pattern = '/^[A-Za-z0-9' . preg_quote( '.%^&()$##!/-+/', '/') . ']{8,30}$/';
The first $pattern expression in your question is missing the required: ^ and $ beginning and end of line assertions - (but the example code snippet which follows uses them correctly.)
You also need to escape the dash/hyphen inside the character class - the hyphen defines a range of characters. (Note that the forward slash / is NOT the escape char!) Try this:
$pattern = '/^[A-Za-z0-9.%^&()$##!\-+\/]{8,30}$/';