-2

I am trying to replace hyphens in text to non-breaking hyphens, but I need to exlude all URLs, emails and tags. Here is some text I am trying to edit:

Some text with a link but also plain URL like http://another-domain.com and an e-mail [email protected] and e-shop and some relative URL like /test-url/on-this-website.

and I came up with this regex: (^|\s+)[^@|^\/]+(\s+|$)

But it cannot be used for preg_replace, it doesn't match hyphens, but whole text that contains dashes.

Result should be:

Some text with a <a href="https://some-domain.com/section-name" class="some-class">link</a> but also plain URL like http://another-domain.com and an e&#8209;mail [email protected] and e&#8209;shop and some relative URL like /test-url/on-this-website.

Have anyone been doing something similar?

1 Answer 1

0

There's a few issues with your regex...

  • You can't use | as an OR operator in your character class
  • Your regex is greedy
  • You can't use multiple not operators in a character class
  • You don't need to have more than one space matched at the start and end
  • Your character class swallows spaces

It seems to me that you're over thinking it; you could rephrase your task to: "replace hyphens in words"

(\s\w+)-(\w+\s)
(\s\w+)            : Capture group matching a white space and then 1 or more of the characters [a-zA-Z0-9_]
        -          : Match a hyphen
         (\w+\s)   : Capture group matching a white space and then 1 or more of the characters [a-zA-Z0-9_]

However, you can also use your more wide ranging character class like:

(\s[^@\/\s]+)-([^@\/\s]+\s)
(\s[^@\/\s]+)                : Capture group matching a space followed by 1 or more characters which aren't  @, /, or a space
             -               : Matches a hyphen
              ([^@\/\s]+\s)  : Capture group matching a space followed by 1 or more characters which aren't  @, /, or a space

$string = "Some text with a link but also plain URL like http://another-domain.com and an e-mail [email protected] and e-shop and some relative URL like /test-url/on-this-website.";

echo preg_replace("/(\s\w+)-(\w+\s)/", "$1&#8209;$2", $string);

echo preg_replace("/(\s[^@\/\s]+)-([^@\/\s]+\s)/", "$1&#8209;$2", $string);

Note: You may need to change the starting and closing space to include the start/end of a the string.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the explanation, I couldn't find proper group regex that would met all conditions. This is exactly what I needed!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.