Auto-link URLs in a string - php

I have a normal message output $msg. I want it to make it links, if it is links. (containing http:// or www.) then it should make it http://google.com
I have stripped html from the messages
$msg = htmlspecialchars(strip_tags($show["status"]), ENT_QUOTES, 'utf-8')
How can that be done, seen it many places.

I had the same problem like #SublymeRick (stops after first dot, see Auto-link URLs in a string).
With a little inspiration from https://stackoverflow.com/a/8218223/593957 I changed it to
$msg = preg_replace('/((http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?)/', '\1', $msg);

Use a regular expression for this, via PHP's preg_replace() function.
Something like this....
preg_replace('/\b(https?:\/\/(.+?))\b/', '\1', $text);
Explaination:
Looks for (https?://(.+?)) surrounded by \b, which is a beginning-of-word / end-of-word marker.
https?:// is obvious (the s? means that the 's' is optional).
(.+?) means any number of any characters: 'any character' is represented by the dot; 'any number of' is the plus sign. The question mark means it isn't greedy, so it will allow the item after it (ie the \b end of word) to match at the first opportunity. This stops it just carrying on till the end of the string.
The whole expression is in brackets so that it gets picked up the the replacement system and can be re-inserted using \1 in the second parameter.

Something like:
preg_replace('#(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)#', '$1', $text);
maybe?

enter code h function AutoLinkUrls($str,$popup = FALSE){
if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches)){
$pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
for ($i = 0; $i < count($matches['0']); $i++){
$period = '';
if (preg_match("|\.$|", $matches['6'][$i])){
$period = '.';
$matches['6'][$i] = substr($matches['6'][$i], 0, -1);
}
$str = str_replace($matches['0'][$i],
$matches['1'][$i].'<a href="http'.
$matches['4'][$i].'://'.
$matches['5'][$i].
$matches['6'][$i].'"'.$pop.'>http'.
$matches['4'][$i].'://'.
$matches['5'][$i].
$matches['6'][$i].'</a>'.
$period, $str);
}//end for
}//end if
return $str;
}//end AutoLinkUrlsere

Related

Remove s or 's from all words in a string with PHP

I have a string in PHP
$string = "Dogs are Jonny's favorite pet";
I want to use regex or some method to remove s or 's from the end of all words in the string.
The desired output would be:
$revisedString = "Dog are Jonny favorite pet";
Here is my current approach:
<?php
$string = "Dogs are Jonny's favorite pet";
$stringWords = explode(" ", $string);
$counter = 0;
foreach($stringWords as $string) {
if(substr($string, -1) == s){
$stringWords[$counter] = trim($string, "s");
}
if(strpos($string, "'s") !== false){
$stringWords[$counter] = trim($string, "'s");
}
$counter = $counter + 1;
}
print_r($stringWords);
$newString = "";
foreach($stringWords as $string){
$newString = $newString . $string . " ";
}
echo $newString;
}
?>
How would this be achieved with REGEX?
For general use, you must leverage much more sophisticated technique than an English-ignorant regex pattern. There may be fringe cases where the following pattern fails by removing an s that it shouldn't. It could be a name, an acronym, or something else.
As an unreliable solution, you can optionally match an apostrophe then match a literal s if it is not immediately preceded by another s. Adding a word boundary (\b) on the end improves the accuracy that you are matching the end of words.
Code: (Demo)
$string = "The bass can access the river's delta from the ocean. The fishermen, assassins, and their friends are happy on the banks";
var_export(preg_replace("~'?(?<!s)s\b~", '', $string));
Output:
'The bass can access the river delta from the ocean. The fishermen, assassin, and their friend are happy on the bank'
PHP Live Regex always helped me a lot in such moments. Even already knowing how REGEX works, I still use it just to be sure some times.
To make use of REGEX in your case, you can use preg_replace().
<?php
// Your string.
$string = "Dogs are Jonny's favorite pet";
// The vertical bar means "or" and the backslash
// before the apostrophe is needed so you don't end
// your pattern string since we're using single quotes
// to delimit it. "\s" means a single space.
$regex_pattern = '/\'s\s|s\s|s$/';
// Fill the preg_replace() with the pattern, the replacement
// (a single space in this case), your string, -1 (so preg_replace()
// will replace all the matches) and a variable of your desire
// to be the "counter" (preg_replace() will automatically
// fill it).
$newString = preg_replace($regex_pattern, ' ', $string, -1, $counter);
// Use the rtrim() to remove spaces at the right of the sentence.
$newString = rtrim($newString, " ");
echo "New string: " . $newString . ". ";
echo "Replacements: " . $counter . ".";
?>
In this case, the function will identify any "'s" or "s" with spaces (\s) after them and then replace them with a single space.
The preg_replace() will also count all the replacements and register them automatically on $counter or any variable you place there instead.
Edit:
Phil's comment is right and indeed my previous REGEX would lose a "s" at the end of the string. Adding "|s$" will solve it. Again, "|" means "or" and the "$" means that the "s" must be at the end of the string.
In attention to mickmackusa's comment, my solution is meant only to remove "s" characters at the end of words inside the string as this was Sparky Johnson' request here. Removing plurals would require a complex code since not only we need to remove "s" characters from plural only words but also change verbs and other stuff.

php regex replace each character with asterisk

I am trying to something like this.
Hiding users except for first 3 characters.
EX)
apple -> app**
google -> goo***
abc12345 ->abc*****
I am currently using php like this:
$string = "abcd1234";
$regex = '/(?<=^(.{3}))(.*)$/';
$replacement = '*';
$changed = preg_replace($regex,$replacement,$string);
echo $changed;
and the result be like:
abc*
But I want to make a replacement to every single character except for first 3 - like:
abc*****
How should I do?
Don't use regex, use substr_replace:
$var = "abcdef";
$charToKeep = 3;
echo strlen($var) > $charToKeep ? substr_replace($var, str_repeat ( '*' , strlen($var) - $charToKeep), $charToKeep) : $var;
Keep in mind that regex are good for matching patterns in string, but there is a lot of functions already designed for string manipulation.
Will output:
abc***
Try this function. You can specify how much chars should be visible and which character should be used as mask:
$string = "abcd1234";
echo hideCharacters($string, 3, "*");
function hideCharacters($string, $visibleCharactersCount, $mask)
{
if(strlen($string) < $visibleCharactersCount)
return $string;
$part = substr($string, 0, $visibleCharactersCount);
return str_pad($part, strlen($string), $mask, STR_PAD_RIGHT);
}
Output:
abc*****
Your regex matches all symbols after the first 3, thus, you replace them with a one hard-coded *.
You can use
'~(^.{3}|(?!^)\G)\K.~'
And replace with *. See the regex demo
This regex matches the first 3 characters (with ^.{3}) or the end of the previous successful match or start of the string (with (?!^)\G), and then omits the characters matched from the match value (with \K) and matches any character but a newline with ..
See IDEONE demo
$re = '~(^.{3}|(?!^)\G)\K.~';
$strs = array("aa","apple", "google", "abc12345", "asdddd");
foreach ($strs as $s) {
$result = preg_replace($re, "*", $s);
echo $result . PHP_EOL;
}
Another possible solution is to concatenate the first three characters with a string of * repeated the correct number of times:
$text = substr($string, 0, 3).str_repeat('*', max(0, strlen($string) - 3));
The usage of max() is needed to avoid str_repeat() issue a warning when it receives a negative argument. This situation happens when the length of $string is less than 3.

Finding and replacing all words that ends with 'ing'

I'm trying to find and replace all words that ends with 'ing'. How would I do that?
$text = "dreaming";
if (strlen($text) >= 6) {
if (0 === strpos($text, "ing"))
//replace the last 3 characters of $text <---not sure how to do this either
echo $text;
echo "true";
}
Result:
null
Want Result:
dream
true
You could also use substr
$text = "dreaming";
if (substr($text, (strlen($text) - 3), 3) === 'ing') {
$text = substr($text, 0, (strlen($text) - 3));
}
echo $text;
This should work for replacing ing at the end of words whilst ignoring stuff starting with Ing as well as words with ing in the middle of them.
$output = preg_replace('/(\w)ing([\W]+|$)/i', '$1$2', $input);
Updated to reflect change specified in comments.
You could use two regexs depending on what you are trying to accomplish your question is a bit ambiguous.
echo preg_replace('/([a-zA-Z]+)ing((:?[\s.,;!?]|$))/', '$1$2', $text);
or
echo preg_replace('/.{3}$/', '', $text);
The first regex looks for word characters before an ing and then punctuation marks, white spaces, or the end of the string. The second just takes off the last three characters of the string.
You can use regex and word boundaries.
$str = preg_replace('/\Bing\b/', "", $str);
\B (non word boundary) matches where word characters are sticking together.
Be aware it substitutes king to k. See demo at regex101

How to replace the Last "s" with "" in PHP

I need to know how I can replace the last "s" from a string with ""
Let's say I have a string like testers and the output should be tester.
It should just replace the last "s" and not every "s" in a string
how can I do that in PHP?
if (substr($str, -1) == 's')
{
$str = substr($str, 0, -1);
}
Update: Ok it is also possible without regular expressions using strrpos ans substr_replace:
$str = "A sentence with 'Testers' in it";
echo substr_replace($str,'', strrpos($str, 's'), 1);
// Ouputs: A sentence with 'Tester' in it
strrpos returns the index of the last occurrence of a string and substr_replace replaces a string starting from a certain position.
(Which is the same as Gordon proposed as I just noticed.)
All answers so far remove the last character of a word. However if you really want to replace the last occurrence of a character, you can use preg_replace with a negative lookahead:
$s = "A sentence with 'Testers' in it";
echo preg_replace("%s(?!.*s.*)%", "", $string );
// Ouputs: A sentence with 'Tester' in it
$result = rtrim($str, 's');
$result = str_pad($result, strlen($str) - 1, 's');
See rtrim()
Your question is somewhat unclear whether you want to remove the s from the end of the string or the last occurence of s in the string. It's a difference. If you want the first, use the solution offered by zerkms.
This function removes the last occurence of $char from $string, regardless of it's position in the string or returns the whole string, when $char does not occur in the string.
function removeLastOccurenceOfChar($char, $string)
{
if( ($pos = strrpos($string, $char)) !== FALSE) {
return substr_replace($string, '', $pos, 1);
}
return $string;
}
echo removeLastOccurenceOfChar('s', "the world's greatest");
// gives "the world's greatet"
If your intention is to inflect, e.g singularize/pluralize words, then have a look at this simple inflector class to know which route to take.
$str = preg_replace("/s$/i","",rtrim($str));
The very simplest solution is using rtrim()
That is exactly what that function is intended to be used for:
Strip whitespace (or other characters) from the end of a string.
Nothing simpler than that, I am not sure why, and would not follow the suggestions in this thread going from regex to "if/else" blocks.
This is your code:
$string = "Testers";
$stripped = rtrim( $string, 's' );
The output will be:
Tester

Replace all certain character except first occurrence in PHP

Example
Input = 1.1.0.1
Expected output = 1.101
You could make use substr() and str_replace() fairly easily:
$str = '1.1.0.1';
$pos = strpos($str,'.');
if ($pos !== false) {
$str = substr($str,0,$pos+1) . str_replace('.','',substr($str,$pos+1));
}
echo $str;
$s = preg_replace('/((?<=\.)[^.]*)\./', '$1', $s);
Matches zero or more non-dot characters followed by a dot, but only if the match was preceded by a dot. This prevents a match on the initial digit(s). Replaces the match with only the non-dot characters (the digits), which were captured in group #1.
$input="1.1.1.1";
$s = explode(".",$input ) ;
$t=array_slice($s, 1);
print implode(".",array($s[0] , implode("",$t)) );
or
$input="1.1.1.1";
$s = explode(".",$input ,2) ;
$s[1]=str_replace(".","",$s[1]);
print implode(".",array($s[0] ,$s[1] ) );
Match&Release the first occurring literal dot
Replace all subsequent literal dots
Code: (Demo)
echo preg_replace('~^[^.]*\.(*SKIP)(*FAIL)|\.~', '', $string);
// 1.101
Or with the "continue" character (\G), consume and forget the first literal dot, then replace all subsequent literal dots.
Code: (Demo)
echo preg_replace('~(?:^[^.]*\.|\G(?!^))[^.]*\K\.~', '', $string);
// 1.101
Or simply check that a literal dot has a literal dot occurring earlier in the string.
Code: (Demo)
echo preg_replace('~(?<=\.)[^.]*\K\.~', '', $string);
// 1.101
I though substr_replace() would work here, but sadly no... Here is a regex approach:
$str = preg_replace('~(\d+\.)(\d+)\.(\d+)\.(\d+)~', '$1$2$3$4', $str);
You could also try the below regex with s switch,
<?php
$string = '1.1.0.1';
$pattern = "/(?s)((?<=\.).*?)(\.)/i";
$replacement = "$1";
echo preg_replace($pattern, $replacement, $string);
?>
Output:
1.101
Using regex matches can be clearer by depicting the desired result and avoids the error-prone approach of calls to substr and strpos. Here I assume that no text is required before the first dot, i.e., that an input may begin with a dot that must be preserved. The difference is whether a quantifier of * or + is appropriate in the patterns below.
If your inputs will always be short, a straightforward approach is to replace trailing dots until none remain:
$count = 0;
$output = $input;
do {
$output = preg_replace('/^(.*\.)(.+)\./', '$1$2', $output, -1, $count);
} while ($count != 0);
echo $output;
To do it with a single regex match, use preg_replace_callback to apply a function (str_replace in this case) to the backreference variable $2.
$output = preg_replace_callback(
'/^([^.]*\.)(.+)$/',
function ($m) { return $m[1] . str_replace('.', '', $m[2]); },
$input);
Sample results:
1.1.0.1 - 1.101
.1.0.1 - .101
111 - 111
1.1 - 1.1
1. - 1.
.1 - .1
.1. - .1
.... - .
You may want to experiment with the code and test cases at Try It Online!

Categories