PHP 正则表达式:删除不完全等于 3 个字符的单词
PHP Regex: Remove words not equal exactly 3 characters
出色的“非常接近”答案位于
Remove words less than 3 chars
DEMO
其中正则表达式
\b([a-z]{1,2})\b
删除所有少于 3 个字符的词。
但是如何重置此演示反之亦然?删除所有不完全等于 3 个字符的单词?
我们可以通过
准确地捕捉到 3 个字符的单词
\b([a-z]{3})\b
但是如何告诉正则表达式 - 删除所有其他不等于 3 的词?
所以在上面的正则表达式演示参考中应该只留下单词 'and'
使用备选方案匹配 1-2 或 4 个以上的字母。
\b(?:[a-z]{1,2}|[a-z]{4,})\b
我想也许:
\b(?![a-z]{3}\b)[a-z]+\b
匹配:
\b
- 单词边界。
(?![a-z]{3}\b)
- 避免三字母单词的否定前瞻。
[a-z]+\b
- 任何 1+ 字母词(贪心)我们到词边界。
另一个技巧是使用捕获组来匹配你想要的:
\b(?:[a-z]{3}|([a-z]+))\b
\b
- 单词边界
(?:[a-z]{3}|([a-z]+))
- 交替内的嵌套捕获组首先忽略三个字母字符并捕获任何 1+ 个单词(贪婪)。
\b
- 单词边界
具有至少 2 个字符和所有格量词的可选字母组:
\b[a-z]{1,2}+(?:[a-z]{2,})?\b
这种方法基于计算技巧和回溯。
换句话说:2 + x = 3 且 x > 1 无解。
如果我写了 \b[a-z]{1,2}(?:[a-z]{2,})?\b
(有或没有最后一个 \b
并不重要),当正则表达式引擎到达三个字母单词开头的位置时 [a-z]{1,2}
会消耗前两个字母,但由于最后一个单词边界需要一个额外的字符才能成功,正则表达式引擎没有其他选择来回溯 {1,2}
量词。通过一个回溯步骤,[a-z]{1,2}
将只消耗一个字符,而 (?:[a-z]{2,})?\b
可能会成功。但是通过使这个量词具有所有格,我禁止了这个回溯步骤。因为对于三个字母的单词,[a-z]{1,2}+
需要 2 个字符而 [a-z]{2,}
至少需要 2 个字母,所以模式失败。
使用词边界并用所有格量词强制失败:
\b(?:[a-z]{3}\b)?+[a-z]+
这个也玩了一个不可能的断言:三个字母后跟一个单词边界,后面不能跟一个字母。
再来一次,三个字母的单词,一旦三个字母被[a-z]{3}
消耗掉,所有格量词?+
禁止回溯,[a-z]+
使模式失效。
用 3 个字母强制失败并使用回溯控制动词跳过它们:
\b[a-z]{3}\b(*SKIP)^|[a-z]+
另一种具有负后视断言左侧不是 3 个字符的变体
\b[a-z]+\b(?<!\b[a-z][a-z][a-z]\b)
或者对 3 个字符 a-z 使用跳过失败方法:
\b[a-z]{3}\b(*SKIP)(*F)|\b[a-z]+\b
出色的“非常接近”答案位于 Remove words less than 3 chars DEMO 其中正则表达式
\b([a-z]{1,2})\b
删除所有少于 3 个字符的词。
但是如何重置此演示反之亦然?删除所有不完全等于 3 个字符的单词? 我们可以通过
准确地捕捉到 3 个字符的单词\b([a-z]{3})\b
但是如何告诉正则表达式 - 删除所有其他不等于 3 的词?
所以在上面的正则表达式演示参考中应该只留下单词 'and'
使用备选方案匹配 1-2 或 4 个以上的字母。
\b(?:[a-z]{1,2}|[a-z]{4,})\b
我想也许:
\b(?![a-z]{3}\b)[a-z]+\b
匹配:
\b
- 单词边界。(?![a-z]{3}\b)
- 避免三字母单词的否定前瞻。[a-z]+\b
- 任何 1+ 字母词(贪心)我们到词边界。
另一个技巧是使用捕获组来匹配你想要的:
\b(?:[a-z]{3}|([a-z]+))\b
\b
- 单词边界(?:[a-z]{3}|([a-z]+))
- 交替内的嵌套捕获组首先忽略三个字母字符并捕获任何 1+ 个单词(贪婪)。\b
- 单词边界
具有至少 2 个字符和所有格量词的可选字母组:
\b[a-z]{1,2}+(?:[a-z]{2,})?\b
这种方法基于计算技巧和回溯。
换句话说:2 + x = 3 且 x > 1 无解。
如果我写了 \b[a-z]{1,2}(?:[a-z]{2,})?\b
(有或没有最后一个 \b
并不重要),当正则表达式引擎到达三个字母单词开头的位置时 [a-z]{1,2}
会消耗前两个字母,但由于最后一个单词边界需要一个额外的字符才能成功,正则表达式引擎没有其他选择来回溯 {1,2}
量词。通过一个回溯步骤,[a-z]{1,2}
将只消耗一个字符,而 (?:[a-z]{2,})?\b
可能会成功。但是通过使这个量词具有所有格,我禁止了这个回溯步骤。因为对于三个字母的单词,[a-z]{1,2}+
需要 2 个字符而 [a-z]{2,}
至少需要 2 个字母,所以模式失败。
使用词边界并用所有格量词强制失败:
\b(?:[a-z]{3}\b)?+[a-z]+
这个也玩了一个不可能的断言:三个字母后跟一个单词边界,后面不能跟一个字母。
再来一次,三个字母的单词,一旦三个字母被[a-z]{3}
消耗掉,所有格量词?+
禁止回溯,[a-z]+
使模式失效。
用 3 个字母强制失败并使用回溯控制动词跳过它们:
\b[a-z]{3}\b(*SKIP)^|[a-z]+
另一种具有负后视断言左侧不是 3 个字符的变体
\b[a-z]+\b(?<!\b[a-z][a-z][a-z]\b)
或者对 3 个字符 a-z 使用跳过失败方法:
\b[a-z]{3}\b(*SKIP)(*F)|\b[a-z]+\b