How to invert preg_match_all php - php

How can I invert pre_match_all, so the output of the code below is "you" instead of "hello" and "world"?
$text1 = array ('you', 'hello', 'WORLD');
$text2 = "Hello world";
//preg_match
foreach ($text1 as $text) {
if (preg_match_all("~\b$text\b~i", $text2, $match)) {
$match = $match[0];
echo "<pre>";
print_r($match);
echo "</pre>";
}
}

Split the string by non-word characters and use array_udiff with strcasecmp as callback:
$words = ['you', 'hello', 'WORLD'];
$str = "Hello world toto";
print_r(array_udiff($words, preg_split('~\W+~', $str), 'strcasecmp'));
// Array
// (
// [0] => you
// )

You don't need preg_match_all(), preg_match() is enough (it returns 1 if it finds a match, 0 otherwise).
You also don't need the matching substrings, it's enough to know if it found a word in the text or not.
$words = array('you', 'hello', 'WORLD');
$text = "Hello world";
// Filter $words, keep only the items that are not present in $text
$missing = array_filter(
$words,
function($w) use ($text) {
// return TRUE when $w is not in $text
return preg_match('/\b'.preg_quote($w, '/').'\b/i', $text) == 0;
});
print_r($missing);

You can use str_ireplace which is case insensitive version of str_replace.
If you replace with nothing, what is left is what is not in $text2.
$text1 = array ('you', 'hello', 'WORLD');
$text2 = "Hello world";
$text2 = explode(" ", $text2);
echo str_ireplace($text2, "", implode("",$text1));
// you
https://3v4l.org/T8o2l
Another method would be to use array_diff and preg_grep.
Preg_grep matches with regex the words from text2 in text1 case insensitive and returns what is matching.
Then I use array_diff to see what is different from $text1 and the return from preg_grep.
$text1 = array ('you', 'hello', 'WORLD');
$text2 = "Hello world";
$text2 = explode(" ", $text2);
Var_dump(array_diff($text1, preg_grep("/" . Implode("|", $text2) . "/i", $text1)));
https://3v4l.org/WOuh6

Related

Use a regex match as an array pointer

I want to replace some numbers in a string with the content of the array in the position which this number points to.
For example, replace "Hello 1 you are great", with "Hello myarray[1] you are great"
I was doing the next: preg_replace('/(\d+)/','VALUE: ' . $array[$1],$string);
But it does not work. How could I do it?
You should use a callback.
<?php
$str = 'Hello, 1!';
$replacements = array(
1 => 'world'
);
$str = preg_replace_callback('/(\d+)/', function($matches) use($replacements) {
if (array_key_exists($matches[0], $replacements)) {
return $replacements[$matches[0]];
} else {
return $matches[0];
}
}, $str);
var_dump($str); // 'Hello, world!'
Since you are using a callback, in the event that you actually want to use a number, you might want to encode your strings as {1} or something instead of 1. You can use a modified match pattern:
<?php
// added braces to match
$str = 'Hello, {1}!';
$replacements = array(
1 => 'world'
);
// added braces to regex
$str = preg_replace_callback('/\{(\d+)\}/', function($matches) use($replacements) {
if (array_key_exists($matches[1], $replacements)) {
return $replacements[$matches[1]];
} else {
// leave string as-is, with braces
return $matches[0];
}
}, $str);
var_dump($str); // 'Hello, world!'
However, if you are always matching known strings, you may want to use #ChrisCooney's solution because it offers less opportunity to screw up the logic.
The other answer is perfectly fine. I managed it this way:
$val = "Chris is 0";
// Initialise with index.
$adj = array("Fun", "Awesome", "Stupid");
// Create array of replacements.
$pattern = '!\d+!';
// Create regular expression.
preg_match($pattern, $val, $matches);
// Get matches with the regular expression.
echo preg_replace($pattern, $adj[$matches[0]], $val);
// Replace number with first match found.
Just offering another solution to the problem :)
$string = "Hello 1 you are great";
$replacements = array(1 => 'I think');
preg_match('/\s(\d)\s/', $string, $matches);
foreach($matches as $key => $match) {
// skip full pattern match
if(!$key) {
continue;
}
$string = str_replace($match, $replacements[$match], $string);
}
<?php
$array = array( 2 => '**', 3 => '***');
$string = 'lets test for number 2 and see 3 the result';
echo preg_replace_callback('/(\d+)/', 'replaceNumber', $string);
function replaceNumber($matches){
global $array;
return $array[$matches[0]];
}
?>
output
lets test for number ** and see *** the result

How do I get the replace to work as I intend in PHP?

I want to make it so that if the words from $hello are entered in $words they are replaced with bonjour but it does not work. How exactly would I go about doing this?
Code:
<?php
$words = $_POST['words'];
$hello = array('hello', 'hi', 'yo', 'sup');
$words = preg_replace('/\b'.$hello.'\b/i', '<span class="highlight">Bonjour</span>', $words);
echo $words;
?>
You are passing an array to your pattern, it should be a string. You can implode this though, something like:
$words = 'Hello world';
$hello = array('hello', 'hi', 'yo', 'sup');
$words = preg_replace('/\b('.implode('|', $hello).')\b/i', '<span class="highlight">Bonjour</span>', $words);
echo $words;
You'll have to decide if you pass an array of patterns to preg_replace
$hello = array('/\bhello\b/i', '/\bhi\b/i', '/\byo\b/i', '/\bsup\b/i');
or a single pattern, i.e by OR:
'/\b('.join('|', $hello).')\b/i'
What you currently pass, is a string like this:
'/\bArray\b/i'
$words = "Would you like to say hi to him?";
$hello = array('hello', 'hi', 'yo', 'sup');
$pattern = "";
foreach ($hello as $h)
{
if ($pattern != "") $pattern = $pattern . "|";
$pattern = $pattern . preg_quote ($h);
}
$words = preg_replace ('/\b(' . $pattern . ')\b/i', 'Bonjour', $words);

How to create a function that can transform the last word into Uppercases?

How do i create a function replaceMe() in php that would turn:
$str = 'This is a very long string';
into:
'This is a very long STRING?'
can someone help me?
You apparently want to do a regular expression substitution, anchored at the end of the line. Use preg_replace:
$str = 'This is a very long string';
# This is a very long LINE
echo preg_replace("/string$/", "LINE", $str);
For a general case, you can provide a callback instead of a replacement string, and simply uppercase the matched substring with preg_replace_callback:
$str = 'This is a very long blah';
function word_to_upper($match) {
return strtoupper($match[1]);
}
# This is a very long BLAH
echo preg_replace_callback("/(\w+)$/", "word_to_upper", $str);
If you're using PHP 5.4 or greater, you can supply the callback as an anonymous function:
echo preg_replace_callback("/(\w+)$/", function ($match) {
return strtoupper($match[1])
}, $str);
This works:
$str = 'This is a very long string';
echo $str."<br/>";
function replaceMe($str = "")
{
$words = explode(" ",$str);
$totalwords = count($words)-1;
$lastword = $words[$totalwords];
$words[$totalwords] = strtoupper($lastword);
$str = implode(" ",$words);
return $str;
}
echo replaceMe($str);
?>
Output:
This is a very long string
This is a very long STRING
$str = 'This is a very long string.';
function lastWordUpper($str){
$temp = strrev($str);
$last = explode(" ", $temp, 2);
return strrev(strtoupper($last[0]). ' ' .$last[1]) ;
}
echo lastWordUpper($str);

String Replace In PHP

i have a long string like
$str = "this is [my] test [string] and [string] is very long [with] so many pwords]"
i know str_replace function, but when i replace
$str = str_replace( "[", "<a href=\"/story.php?urdu=",$str;
$str = str_replace( "]", "\"></a>",$str;
i got this result
but i want this result for each word in []
test
You should use preg_replace() for this one.
Code
<?php
function replace_matches($matches) {
$text = htmlspecialchars($matches[1]);
$url = urlencode($matches[1]);
return "{$text}";
}
$str = "this is [my] test [string] and [<script>alert(1)</script>] is very long [with] so many pwords]";
$str = preg_replace_callback("%\[(.+?)\]%", "replace_matches", $str);
echo $str;
?>
Working Example
$str = preg_replace_callback(
'/\[([^\]]*)\]/',
function($matches) {
return sprintf('%s',
urlencode($matches[1]),
htmlspecialchars($matches[1]));
},
$str);

Check if any array values are present at the end of a string

I am trying to test if a string made up of multiple words and has any values from an array at the end of it. The following is what I have so far. I am stuck on how to check if the string is longer than the array value being tested and that it is present at the end of the string.
$words = trim(preg_replace('/\s+/',' ', $string));
$words = explode(' ', $words);
$words = count($words);
if ($words > 2) {
// Check if $string ends with any of the following
$test_array = array();
$test_array[0] = 'Wizard';
$test_array[1] = 'Wizard?';
$test_array[2] = '/Wizard';
$test_array[4] = '/Wizard?';
// Stuck here
if ($string is longer than $test_array and $test_array is found at the end of the string) {
Do stuff;
}
}
By end of string do you mean the very last word? You could use preg_match
preg_match('~/?Wizard\??$~', $string, $matches);
echo "<pre>".print_r($matches, true)."</pre>";
I think you want something like this:
if (preg_match('/\/?Wizard\??$/', $string)) { // ...
If it has to be an arbitrary array (and not the one containing the 'wizard' strings you provided in your question), you could construct the regex dynamically:
$words = array('wizard', 'test');
foreach ($words as &$word) {
$word = preg_quote($word, '/');
}
$regex = '/(' . implode('|', $words) . ')$/';
if (preg_match($regex, $string)) { // ends with 'wizard' or 'test'
Is this what you want (no guarantee for correctness, couldn't test)?
foreach( $test_array as $testString ) {
$searchLength = strlen( $testString );
$sourceLength = strlen( $string );
if( $sourceLength <= $searchLength && substr( $string, $sourceLength - $searchLength ) == $testString ) {
// ...
}
}
I wonder if some regular expression wouldn't make more sense here.

Categories