Remove text after link - php

So I have an #mentions function on my site that users input themselves but can do something line:
#foo Hello This is some mention text included.
I would like to remove just the text (Everything after #foo) The content comes through the streamitem_content:
$json['streamitem_content_usertagged'] =
preg_replace('/(^|\s)#(\w+)/', '\1#$1',
$json['streamitem_content']);

Give this a try
$json['streamitem_content'] = '#foo Hello This is some mention text included.';
$json['streamitem_content_usertagged'] =
preg_replace('/#(\w+)/', '#$1',
$json['streamitem_content']);
echo $json['streamitem_content_usertagged'];
Output:
#foo Hello This is some mention text included.
Preg_replace will only replace what it finds so you don't need to find content you aren't interested. If you did want to capture multiple parts of a string though capture groups increase by one after each group (). So this
preg_replace('/(^|\s)#(\w+)/', '$1#$2',
$json['streamitem_content']);
echo $json['streamitem_content_usertagged'];
would actually be
preg_replace('/(^|\s)#(\w+)/', '$1#$2',
$json['streamitem_content']);
Update:
$json['streamitem_content'] = '#foo Hello This is some mention text included.';
$json['streamitem_content_usertagged'] =
preg_replace('/#(\w+).*$/', '#$1',
$json['streamitem_content']);
echo $json['streamitem_content_usertagged'];
Output:
#foo
If the content you want to replace after #foo can extended to multiple lines use the s modifier.
Regex101 Demo: https://regex101.com/r/tX1rO0/1
So pretty much the regex says find an # then capture all continuous a-zA-Z0-9_ characters. After a those continuos characters we don't care go to the end of the string.

You can use this:
preg_replace('/^\s*#(\w+)/', '#$1',
$json['streamitem_content']);
This removes the leading white space, and includes the # in the hyperlink's text (not the link argument).
If you need to keep the leading white space in tact:
preg_replace('/^(\s*)#(\w+)/', '$1#$2',
$json['streamitem_content']);

You could use explode(); and str_replace(); . They might have a speed advantage over preg.
Assuming the line is available as a variable (e.g. $mention):
$mention = $json['streamitem_content'];
$mention_parts = explode(" ", $mention);
$the_part_you_want = str_replace('#','', $mention_parts[0]);
// or you could use $the_part_you_want = ltrim($mention_parts[0], '#');
$json['streamitem_content_usertagged'] = '#' . $mention_parts[0] . '';
or use trim($mention_parts[0]); to remove any whitespace if it is unwanted.
You could use fewer variables and reuse $mention as array but this seemed a clearer way to illustrate the principle.

Related

Change ocurrence inside a string

I am needing to change occurrence of string or numbers in php. In this situation, I need to change this, if it happens:
[code:154545edppy]
// my code here
[/code]
to this
[code]
// my code here
[/code]
I need to verify if letters and strings appear inside de opening block code. I am trying to do this with str_replace, but it's not working.
my code now:
$text = "[code:54as] [/code]";
$text = str_replace("[code: {(\d)}{(\w)}]", "[code]", $text);
$text = str_replace("[/code: {(\d)}{(\w)}]", "[/code]", $text);
echo $text;
str_replace is static. Use preg_replace with a regex and you can accomplish your task.
Something like:
$text = "[code:54as] [/code]";
echo preg_replace('~(\[/?.*?):.*?\]~', '$1]', $text);
Should do it.
PHP Demo: https://eval.in/643544
Regex demo: https://regex101.com/r/mD1bM3/1
If you only want to replace numbers and letters after the : use a character class in place of the second .*?. [A-Za-z\d]*?.

Make user name bolded in text in PHP

$text = 'Hello #demo here!';
$pattern = '/#(.*?)[ ]/';
$replacement = '<strong>${1}</strong> ';
echo preg_replace($pattern, $replacement, $text);
This works, I get HTML like this: Hello <strong>demo</strong> here!. But this not works, when that #demo is at the end of string, example: $text = 'Hello #demo';. How can I change my pattern, so it will return same output whenever it is end of the string or not.
Question 2:
What if the string is like $text = 'Hello #demo!';, so it will not put ! as bolded text? Just catch space, end of string or not real-word.
Sorry for bad English, hope you know what I need.
In order to select a word beginning with the # symbol, this regex will work:
$pattern = "/#(\w+)\b/"
`\w` is a short hand character class for `[a-zA-Z0-9_]`. `\b` is an anchor for the beginning or end of a word, in this case the end. So the regex is saying: select something starting with an '#' followed by one or more word characters until the end of the word is reached.
Reference: http://www.regular-expressions.info/tutorial.
You could use a word boundary, that's what they're for:
$pattern = '/#(.+?)\b/';
This will work for question 2 also
You can add an option to match the end of the string:
#(.*?)(?= |\p{P}?$)
Replace with <strong>$1</strong>.
You can also use \p{P} (any Unicode punctuation symbol) to prevent punctuation from bold formatting.
Here is a demo.

Regex to trim text between tags

I expected this to be a simple regex but I guess my head isn't screwed on this morning!
I'm taking the source code of a page and tidying it up with a bunch of other preg_replaces, so by the time we get to the regex below, the result is already a single line string with things like comments stripped out, etc.
All I'm looking to do now is trim the texts between > and < char's down to remove extra whitespace. I.e.
<p> hello world </p>
should become
<p>hello world</p>
I figured this would do the trick, but it seems to do nothing?
$data = trim(preg_replace('/>(\s*)([^\s]*?)(\s*)</', '>$2<', $data));
Cheers.
Here's a ridiculous way to do it lol:
$str = "<p> hello world </p>";
$strArr = explode(" ", $str);
$strArr = array_filter($strArr);
var_dump(implode(" ",$strArr));
Use the power of arrays to remove the white spaces lol
you can use the /e modifier in regex to use the trim() function while replacing.
$data = preg_replace('/>([^<]*)</e', '">" . trim("$1") . "<"', $data);
A regex could be:
>\s+(.*[^\s])\s+<
but don't use it, there are better ways to reach that goal (example: HTMLtidy)
You may use this snippet of code.
$x = '<p> hello world </p>';
$foo = preg_replace('/>\s+/', '>', $x); //first remove space after ">" symbol
$foo = htmlentities(preg_replace('/\s+</', '<', $foo)); //now remove space before "<" symbol
echo $foo;

Regex for breaking repeated characters

I have a comment box on my site , what I want here is if a user writes input (any character) which is more than 20 characters and doesnot put space between them then it should place a space between it.
Like: "asdasdasdasdasdasdasdasd"
Parsed: "asdasdasdasdasdasdas dasd"
I think it can be done with string compare but I want the regex to match it or the full solution. Thanks for any help.
it is called word wrapping.
http://php.net/manual/en/function.wordwrap.php
from examples :
<?php
$text = "A very long woooooooooooord.";
$newtext = wordwrap($text, 8, " ", true);
echo "$newtext\n";
?>
output:
A very long wooooooo ooooord.
The function wordwrap does this job well. But here is a regex based solution:
$str = "asdasdasdasdasdasdasdasd";
$str = preg_replace('/(.{20})/','$1 ',$str);
This will put add a space even if the input is of size 20. If you don't want that use:
$str = preg_replace('/(.{20})(?=.)/','$1 ',$str);

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