匹配字符集和可选实体

3
所以我想使用这个代码在每5个字符中插入一个单词分隔符。
([^\s-]{5})([^\s-]{5})

不幸的是,它也会在实体字符(&#xxx;)上中断。 有人能提供一个不会破坏实体代码的示例吗? 我想要打破的字符串来自xml,因此实际实体进一步转义(&#xxx;)。

编辑代码示例

preg_replace('/([^\s-]{5})([^\s-]{5})/', '$1­$2', $subject)

Given the word "Fårevejle"
Expect "Få­revejle" as result
But it outputs "F­5;revejle" instead

那不是代码,只是一个正则表达式本身并没有做太多事情。你能展示一下你正在使用这个正则表达式的实际代码以及一个样本字符串,在此之前和之后的样子吗?特别是你想要它变成什么样子,而不是现在得到的结果。 - Tim Pietzcker
那么命名实体&&quot<>呢?十六进制实体/&#x[A-Fa-f0-9]+;/呢?如果数字实体代表连字符或空格字符怎么办? - Alan Moore
1个回答

4

假设您想在每个单词的五个字符后拆分,除非它们已经被连字符分隔,将实体视为单个字符,请尝试以下方法:

$result = preg_replace(
    '/            # Start the match 
    (?:           # at one of the following positions:
     (?<=         # Either right after...
      [\s-]       # a space or dash
     )            # end of lookbehind
     |            # or...
     \G           # wherever the last match ended.
    )             # End of start condition.
    (             # Now match and capture the following:
     (?>          # Match the following in an atomic group:
      &amp;\#\w+; # an entity
      |           # or
      [^\s-]      # a non-space, non-dash character
     ){5}         # exactly 5 times.
    )             # End of capture
    (?=[^\s-])    # Assert that we\'re not at the end of a "word"/x', 
    '\1&shy;', $subject);

这会带来变化。

supercalifragilisticexpidon'tremember! 
alrea-dy se-parated 
count entity as one character&amp;#345;blahblah
F&amp;#xe5;revejle

转换为

super&shy;calif&shy;ragil&shy;istic&shy;expid&shy;on'tr&shy;ememb&shy;er! 
alrea-dy se-parat&shy;ed 
count entit&shy;y as one chara&shy;cter&amp;#345;&shy;blahb&shy;lah
F&amp;#xe5;rev&shy;ejle

聪明。很好!唯一让我有点困扰的是使用\b - 它与OP对单词字符的定义不完全相同(例如,如果我理解正确,它不会在a !!!!!? b中添加破折号)。 - Kobi
顺便说一下,我走了一条捷径;我没有检查跟在“&#”后面的内容是否真的是十六进制数。 - Tim Pietzcker
F&amp;#xe5;revejle 上运行正常,但在这些 "&amp;#xd8;ster Hurup Strand" > "&.#xd8;.ster Hurup Stran.d""Danmark - B&amp;#xf8;ged Strand" > "Danma.rk - B&.;#xf8.;ged Stran.d"(点表示 shy)上无法正常工作。 - ken
F&amp;#xe5;revejle 上运行正常,但在这些 "&amp;#xd8;ster Hurup Strand" > "&amp;.#xd8;.ster Hurup Stran.d""Danmark - B&amp;#xf8;ged Strand" > "Danma.rk - B&amp.;#xf8.;ged Stran.d"(点表示 shy)上无法正常工作。 - ken
啊,是的,如果包含实体的单词少于5个字符,正则表达式就会失败。但修复它很容易(我想):我只需要将非捕获组围绕着5个字符改为原子组,防止正则表达式引擎回溯并拆分实体。请现在尝试一下。 - Tim Pietzcker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接