我如何计算两个单词之间的单词数?

tur*_*bod 1 php pcre

我如何计算两个单词之间的单词数?

   $txt = "tükörfúrógép banana orange lime, tükörfúrógép cherry árvízt?r? orange lyon
    cat lime mac tükörfúrógép cat orange lime cat árvízt?r?
    tükörfúrógép banana orange lime
    orange lime cat árvízt?r?";
Run Code Online (Sandbox Code Playgroud)

这两个词:"árvíztűrő"和"tükörfúrógép"
我需要这个回报:
tükörfúrógép樱桃árvíztűrő
tükörfúrógép猫橙色石灰猫árvíztűrő
tükörfúrógép香蕉橘子橙子石灰石灰猫árvíztűrő

现在我有这个正则表达式:

preg_match_all('@((tükörfúrógép(.*)?árvízt?r?)(árvízt?r?(.*)?tükörfúrógép))@sui',$txt,$m);
Run Code Online (Sandbox Code Playgroud)

Tom*_*lak 7

我有几点需要指出:

  1. 你不能在一个正则表达式中做到这一点.正则表达式仅向前,反向匹配顺序需要第二个正则表达式.
  2. 你用(.*)?,但你的意思是 (.*?)
  3. 要获取正确的匹配项,必须确保表达式的左边界不能出现在中间.
  4. 您应该\b在分隔符词周围表示单词边界()以确保整个单词匹配. 编辑:虽然这在理论上是正确的,但它不适用于PHP中的Unicode输入.
  5. 您应该在调用之前将PHP语言环境切换为匈牙利语(它匈牙利语,对吗?)preg_match_all(),因为语言环境会影响PHP中的单词边界. 编辑:\b事实上的含义实际上不会随选定的区域设置改变.

话虽这么说,正则表达式#1是:

(\btükörfúrógép\b)((?:(?!\1).)*?)\bárvízt?r?\b

和正则表达式#2是类似的,只是用反向分隔词.

正则表达式解释:

(               # match group 1:
  \b            #   a word boundary
  tükörfúrógép  #   your first delimiter word
  \b            #   a word boundary
)               # end match group 1
(               # match group 2:
  (?:           #   non-capturing group:
    (?!         #     look-ahead:
      \1        #       must not be followed by delimiter word 1
    )           #     end look-ahead
    .           #     match any next char (includes \n with the "s" switch)
  )*?           #   end non-capturing group, repeat as often as necessary
)               # end match group 2 (this is the one you look for)
\b              # a word boundary
árvízt?r?       # your second delimiter word
\b              # a word boundary
Run Code Online (Sandbox Code Playgroud)

更新:使用PHP 可怜的 Unicode字符串支持,您将被迫使用这些表达式作为替换\b:

$before = '(?<=^|[^\p{L}])';
$after  = '(?=[^\p{L}]|$)';
Run Code Online (Sandbox Code Playgroud)

这个建议来自另一个问题.