我找到了一些部分帮助,但似乎无法完全实现我的需要。我需要能够做到以下几点:
我需要一个正则表达式来替换长度超过3个字符的两个单词之间的任何1到3个字符的单词,并匹配任何表达式:
例如:
walk to the beach ==> walk(.*)beach
如果1到3个字符的单词前面没有超过3个字符的单词,那么我想将1到3个字母单词翻译成'<word> ?'
例如:
on the beach ==> on ?the ?beach
规则越简单越好(当然,如果有更复杂的替代版本,那么我会更好地使用它,以及最终预计会大量使用)。
这将在最有可能与preg_replace
一起使用的PHP上下文中使用。因此,如果你能把它放在那个环境中,那就更好了!
顺便说一下,到目前为止,我有以下几点:
$string = preg_replace('/\s+/', '(.*)', $string);
$string = preg_replace('/\b(\w{1,3})(\.*)\b/', '${1} ?', $string);
但结果是:
walk to the beach ==> 'walk(.*)to ?beach'
这不是我想要的。 'on the beach'
似乎正确翻译。
答案 0 :(得分:-2)
我认为你需要两个替代品。让我们从第一个要求开始:
$str = preg_replace('/(\w{4,})(?: \w{1,3})* (?=\w{4,})/', '$1(.*)', $str);
当然,您需要将那些\w
(字母,数字和下划线匹配)替换为您实际想要作为单词字符处理的字符类。
第二个有点困难,因为匹配不能重叠,并且lookbehinds不能是可变长度。所以我们必须在循环中多次运行:
do
{
$str = preg_replace('/^\w{0,3}(?: \w{0,3})* (?!\?)/', '$0?', $str, -1, $count);
} while($count);
这里我们匹配字符串开头的所有内容,只要它是由空格分隔的最多3个字母的单词,加上一个尾随空格(仅当尚未跟随时)由?
)。然后我们将所有这些放回原位,并附加?
。
<强>更新强>
在评论中的所有讨论之后,这是一个更新的解决方案。
在运行第一行之后,我们可以假设只留下少于3个字母的单词将位于字符串的开头或结尾。所有其他人将被折叠为(.*)
。由于你想在?
之间追加所有空格,你甚至不需要循环(事实上这些是唯一的空格):
$str = preg_replace('/ /', ' ?', $str);
(在我的第一行代码之后立即执行此操作。)
这将给出以下两个结果(与第一行结合):
let us walk on the beach now go => let ?us ?walk(.*)beach ?now ?go
let us walk on the beach there now go => let ?us ?walk(.*)beach(.*)there ?now ?go