Need a Good Regex to Convert Urls to Links But Leave Existing Links Alone

How can I convert URLs to Markdown syntax, but NOT interfere with URLs already in Markdown syntax?

I think (?<!\() is what you meant. If the match position is at the beginning of, it's not the next character you need to check, but the previous one. In other words you need a negative lookbehind, not a negative lookahead.

RegEx to convert URLs in text into clickable ones with custom anchor text

"But I cannot get the order of \1 and \2 right"

The number of the capturing groups are in the order of the opening brackets, so the first opening bracket will always be $1. If you don't want that, use named groups.

For your problem you can try this regex


It will have "here" in $1 and the link in $2. If "here" is not found then $1 is empty.

See it here on Regexr

So, then you need to replace dependent on the content of $1. If it is empty then replace the match with

<a href="$2">$2</a>

else with

<a href="$2">$1</a>

I think this should be possible using preg_replace_callback

PHP find all links in the text

I'd go with something simple like ~[a-z]+://\S+~i

  • starts with protocol [a-z]+://
  • \S+ followed by one or more non-whitespaces where \S is a shorthand for [^ \t\r\n\f]
  • used modifier i (PCRE_CASELESS) (possibly not really necessery)

So it could look like this:

$pattern = '~[a-z]+://\S+~';

$str = 'Test text Test text Test text https://hell.o.wor.ld/test?qwe=qwe Test text
test text http://test.test/test';

if($num_found = preg_match_all($pattern, $str, $out))
echo "FOUND ".$num_found." LINKS:\n";


[0] =>
[1] =>
[2] => https://hell.o.wor.ld/test?qwe=qwe
[3] => http://test.test/test

Test on

Linkify text with regular expressions in Java

You are close. You can use a "negative lookbehind" like so:

(?<!href=")http:// etc

All results preceded by href will be ignored.

Automatically hyper-link URL's and Email's using C#, whilst leaving bespoke tags in place

Here's the method I use. I don't have access right now to the full codebase so can't see how that fits in alongside the forum-code to stop double-linking, but try it out and see if it works for you...

/// <summary>
/// Turns any literal URL references in a block of text into ANCHOR html elements.
/// </summary>
public static string ActivateLinksInText(string source)
source = " " + source + " ";
// easier to convert BR's to something more neutral for now.
source = Regex.Replace(source, "<br>|<br />|<br/>", "\n");
source = Regex.Replace(source, @"([\s])(www\..*?|http://.*?)([\s])", "$1<a href=\"$2\" target=\"_blank\">$2</a>$3");
source = Regex.Replace(source, @"href=""www\.", "href=\"http://www.");
//source = Regex.Replace(source, "\n", "<br />");
return source.Trim();

Regular expression replace a word by a link

You could search for this regular expression:


This regex matches a link, which it captures into the first (and only) capturing group, or the word Paris.

Replace the match with your link only if the capturing group did not match anything.

E.g. in C#:

resultString = 
new MatchEvaluator(ComputeReplacement));

public String ComputeReplacement(Match m) {
if (m.groups(1).Success) {
return m.groups(1).Value;
} else {
return "<a href=\"link to paris\">Paris</a>";

creating hyperlinks from plain text

There are heaps of duplicates of this question, which is the very fact that makes it more difficult to find the right one. Accept this list instead:

  • How do I linkify urls in a string with php?
  • regex to turn URLs into links without messing with existing links in the text
  • PHP - Function To Find Links In Text
  • Need a good regex to convert URLs to links but leave existing links alone

But since you already have something that you think works for you, there would be the option to just add the edge case. Finding is not easy and likely leads to false positives. But converting them to http:// urls so the other rules pick them up would be possible by applying this first:

$text = preg_replace('#(?<!://)w+\.\w+\.(com|net|org|\w\w)\b\S*#', "http://$0", $text);
$text = preg_replace('#(?<!://)www\.\S+#', "http://$0", $text);

Instead of \S you could use your lengthy character class.

Related Topics

Leave a reply