【问题标题】:Mask all characters with preg_replace except some needles用 preg_replace 屏蔽所有字符,除了一些针
【发布时间】:2016-12-05 12:26:50
【问题描述】:

使用 PHP preg_replace 和正则表达式

$string_1 = "leave sb. alone";
$string_2 = "pick one's way forward";
$string_2 = "suffer from sth.";

我需要用指定的字符屏蔽每个字符串,但保留空格、撇号和一些字符串不变,例如:

$mask_1 = "XXXXX sb. XXXXX";
$mask_2 = "XXXX XXX'X XXX XXXXXXX";
$mask_2 = "XXXXXX XXXX sth.";

在这种情况下,我想保留:sb。某事空格和撇号。 任何帮助将不胜感激。

$mask_1 = preg_replace('/(sb.\K)?./s', 'X', $string_1); 我只留下'sb'。但空间仍在变化。

PS:@Casimir et Hippolyte 和@Wiktor Stribiżew 的答案都是很好的解决方案,但我接受了 Wiktor 的 SKIP-FAIL 实施和解释。非常感谢!

【问题讨论】:

  • 好的,好的。那么你的问题是什么?您显然想要替换除某些特定字符和某些短语之外的所有字符。去做吧。
  • @arkascha 感谢您的建议。

标签: php regex


【解决方案1】:

您可以使用 SKIP-FAIL 正则表达式:

'~(?:s(?:b|th)\.|[\s'])(*SKIP)(*F)|.~'

regex demo

详情

  • (?:s(?:b|th)\.|[\s']) - 匹配s,然后匹配b (sb) 或th (sth),然后匹配. 或空格或' ([\s'])
  • (*SKIP)(*F) - 省略匹配,从匹配文本的末尾开始寻找下一个匹配
  • | - 或
  • . - 匹配换行符以外的字符(添加 DOTALL 修饰符也匹配换行符)

如果您需要匹配要保留的整个单词,请不要忘记添加单词边界,\b(例如 '~(?:\bs(?:b|th)\.|[\s'])(*SKIP)(*F)|.~')。

【讨论】:

【解决方案2】:

您可以针对您想要的字符进行测试:

(?:\G|\b(?!sb\.|sth\.))[[:alnum:]]

(您也可以将[[:alnum:]] 更改为\w[^\W_]

demo

或者这个使用\K跳过你不想要的字符:

\G(?:\W*(?:\bs(?:b|th)\.)?)*+\K.

demo

在这两种模式中,\G 保证了连续性。

【讨论】:

  • 谢谢,在 regex101.com 上看起来很棒,但我无法嵌入到 php preg_replace 中。请指教。
  • @Karls: regex101 有一个代码生成器功能,点击链接看看你错过了什么。也许是分隔符?
  • $mask_1 = preg_replace('/\G(?:\W*(?:\bs(?:b|th)\.)?)*+\K./gs', 'X', $string_1);
  • @NicolasMaltais:是的,没有 g。
  • @Casimir et Hippolyte 好的,找到了,太棒了,谢谢!现在它的作品。是否有任何简单的方法可以向正则表达式添加更多异常,例如:“sb.'s”?
猜你喜欢
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
相关资源
最近更新 更多