PHP中的正则表达式:如何在字母数字字符之间替换连字符?

时间:2014-05-03 16:04:08

标签: php regex

我试图找到然后用en和em宽度替换连字符的实例。

因此,在示例中:" 10-100"连字符将由en宽度替换。此外,在例子中:"毫无疑问,它是最糟糕的"或者:"毫无疑问,这是最糟糕的"任何一个实例都将替换为em宽度。

但是,我无法在PHP中找出preg_replace()的正确模式。

"/[0-9]+(\-)[0-9]+/"

...似乎进行了替换,但删除了数字。

如何让preg_replace()忽略主题两侧的模式?

2 个答案:

答案 0 :(得分:1)

您可以使用lookbehinds和lookaheads:

function prettyDashes($string) {
    static $regex = array(
        '/(?<=\d)-(?=\d)/' => '&ndash;',  // EN-dash
        '/(?<=\s)-(?=\s)/' => '&mdash;',  // EM-dash
        '/(?<=\w)--(?=\w)/' => '&mdash;', // EM-dash
    );
    return preg_replace(array_keys($regex), array_values($regex), $string);
}
$tests = array(
    'There are 10-20 dogs in the kennel.',
    'My day was - without a doubt - the worst!',
    'My day was--without a doubt--the worst!',
);
foreach ($tests as $test) {
    echo prettyDashes($test), '<br>';
}

问题是在更换这样的东西时很难检测并避免误报。正常的带连字符的单词,如&#34; to-do&#34;,不是切线(em-dash),而日期,如18-12-2014,不是范围(en-dash)。你必须对你所取代的东西保守相当,如果错误地改变某些事情你就不应该感到惊讶。

答案 1 :(得分:0)

所以,感谢@mario,答案是:

"/(?=.*?[0-9])(\-)(?=.*?[0-9])/"

"/(?=.*?\w)( \- )(?=.*?\w)/"

"/(?=.*?\w)( \-- )(?=.*?\w)/"