Php 正则表达式替换文本中的连字符,不包括URL、标记和邮件

Php 正则表达式替换文本中的连字符,不包括URL、标记和邮件,php,regex,preg-replace,Php,Regex,Preg Replace,我试图将文本中的连字符替换为不间断的连字符,但我需要排除所有URL、电子邮件和标记。以下是我试图编辑的一些文本: 有些文本带有链接,但也有普通URL,如 还有一封电子邮件info@some-domain.com和 e-shop和一些相关的URL,比如这个网站上的/testurl/ 我想出了这个正则表达式:(^ |\s+)[^@| ^\/]+(\s+|$) 但它不能用于preg\u replace,它不匹配连字符,而是包含破折号的整个文本 结果应该是: Some text with a <a

我试图将文本中的连字符替换为不间断的连字符,但我需要排除所有URL、电子邮件和标记。以下是我试图编辑的一些文本:

有些文本带有链接,但也有普通URL,如 还有一封电子邮件info@some-domain.com和 e-shop和一些相关的URL,比如这个网站上的/testurl/

我想出了这个正则表达式:
(^ |\s+)[^@| ^\/]+(\s+|$)

但它不能用于
preg\u replace
,它不匹配连字符,而是包含破折号的整个文本

结果应该是:

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 info@some-domain.com and e&#8209;shop and some relative URL like /test-url/on-this-website.
一些带有普通URL的文本,如http://another-domain.com 和e‑;邮寄info@some-domain.com和e‑;在这个网站上购物和一些相关的URL,比如/test URL/。

有人做过类似的事情吗?

您的正则表达式有一些问题

  • 不能将
    |
    用作角色类中的OR运算符
  • 你的正则表达式很贪婪
  • 不能在字符类中使用多个
    not
    运算符
  • 您不需要在开始和结束处匹配多个空格
  • 你的角色类会吞噬空格

在我看来,你想得太多了;您可以将任务改为:“替换单词中的连字符”

但是,您也可以使用范围更广的字符类,如:

(\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 info@some-domain.com 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);

注意:您可能需要更改起始和结束空格以包含字符串的开始/结束。

感谢您的解释,我找不到满足所有条件的正确组正则表达式。这正是我需要的!
(\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 info@some-domain.com 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);