正在寻找一个php正则表达式,它将允许我从单词中分离出某些字符(如果它们位于单词的左侧或右侧,甚至位于单词内的任何位置)。
例如,
hello. -> hello .
.hello -> . hello
hello.hello -> hello . hello
我有下面的代码,但它不适用于所有情况。请注意,$value可以是"."、"?"、,或任何字符。
$regex = "/(?<='S)''" . $value . "|''" . $value . "(?='S)/";
$this->str = preg_replace_callback($regex, function($word) {
return ' ' . $word[0];
}, $this->str);
此外,请帮助指定我可以打开(或关闭)第三个条件的部分。
[更新]我认为可能会对确切的要求感到困惑。让我试着说得更具体一些。我想要一个正则表达式,它将帮助我分离出一组文本的末尾或开头的某些字符。什么是文本组?文本组可以是任何长度(>=1)并包含任何字符,但必须以a-z或0-9开头。同样,如果这个方面能在解决方案中突出显示,那么如果我们想要一组文本以&以更多字符结尾(不仅仅是a-z或0-9)是可能的。
$character = '.', string is ".hello.world." => ". hello.world ."
$character = '.', string is ".1ello.worl2." => ". 1ello.worl2 ."
$character = '.', string is ".?1ello.worl2." => ".?1ello.worl2 ."
$character = '.', string is "4/5.5" => "4/5.5"
$character = '.', string is "4.?1+/5" => "4.?1+/5"
$character = '.', string is ".4/5.5." => ". 4/5.5 ."
$character = '/', string is ".hello?.world/" => ".hello?.world /"
$character = '/', string is ".hello?.worl9/" => ".hello?.worl9 /"
希望,现在更清楚了。
您可以使用3个备选方案,每个备选方案都被捕获到自己的捕获组中,并使用preg_replace_callback
应用相应的替换:
$wrd = ".";
$re = '~(?<='S)(' . preg_quote($wrd) . ')(?='S)|(?<='S)(' . preg_quote($wrd) . ')|(' . preg_quote($wrd) . ')(?='S)~';
$str = "hello.'n.hello'nhello.hello";
$result = preg_replace_callback($re, function($m) {
if (!empty($m[1])) {
return " " . $m[1] . " ";
} else if (!empty($m[2])) {
return " " . $m[2];
} else return $m[3] . " ";
}, $str);
echo $result;
查看IDEONE演示
正则表达式将是
(?<='S)('.)(?='S)|(?<='S)('.)|('.)(?='S)
| 1| | 2| | 3|
参见regex演示
第一组为病例3(hello.hello -> hello . hello
),第二组为病例1(hello. -> hello .
),第三组为病例2(.hello -> . hello
)。
更新(处理异常)
如果有异常,可以添加更多的捕获组。例如,您希望保护浮点数中的点。添加一个('d'.'d)
替代项,并在回调函数内部检查它是否为空。如果没有,只需使用return $m[n]
:恢复即可
$wrd = ".";
$re = '~('d'.'d)|(?<='S)(' . preg_quote($wrd) . ')(?='S)|(?<='S)(' . preg_quote($wrd) . ')|(' . preg_quote($wrd) . ')(?='S)~';
$str = "hello.'n.hello'nhello.hello'nhello. 3.5/5'nhello.3'na./b";
$result = preg_replace_callback($re, function($m) {
if ( !empty($m[1])) { // The dot as a decimal separator
return $m[1]; // No space is inserted
}
else if (!empty($m[2])) { // A special char is enclosed with non-spaces
return " " . $m[2] . " "; // Add spaces around
} else if (!empty($m[3])) { // A special char is enclosed with non-spaces
return " " . $m[3]; // Add a space before the special char
} else return $m[4] . " "; // A special char is followed with a non-space, add a space on the right
}, $str);
echo $result;
查看更新的代码演示
另一个代码演示-基于.
前后没有空格的匹配位置(并保护浮点值)(基于@bobblebubble的解决方案(已删除)):
$wrd = ".";
$re = '~('d'.'d)|(?<!'s)(?=' . preg_quote($wrd) . ')|(?<=' . preg_quote($wrd) . ')(?!'s)~';
$str = "hello.'n.hello'nhello.hello'nhello. 3.5/5'nhello.3'na./b";
$result = preg_replace_callback($re, function($m) {
if ( !empty($m[1])) { // The dot as a decimal separator
return $m[1]; // No space is inserted
}
else return " "; // Just insert a space
}, $str);
echo $result;
摘要:
- 您不能使用
'b
,因为您的.
/?
等可以出现在混合的"单词"answers"非单词"上下文中 - 您需要使用捕获和
preg_replace_callback
,因为有不同的替换方案
您可以使用基于单词边界的正则表达式。
'b(?='.(?!'S))|(?<=(?<!'S)'.)'b
如果后面没有非空白'S
或前面没有使用查找表检查的非空白,将匹配单词和文字点之间的边界(零宽度)。
请参阅regex101中的演示。在带有值参数的PHP函数中使用,并替换为空格。
// $v = character
function my_func($str, $v=".")
{
$v = preg_quote($v, '/');
return preg_replace('/'b(?='.$v.'(?!'S))|(?<=(?<!'S)'.$v.')'b/', " ", $str);
}
在eval.in 上的PHP演示
据我所知,.
可以是任何非单词字符。如果是这样的话,试试这个:
$patron = '/('W+)/';
$this->str = trim(preg_replace($patron, ' $1 ', $this->str));
('s?[.]'s?)
如果您使用上面的regex,您可以简单地将所有匹配项替换为" . "
工作原理:
我使用's?
来捕获前导和尾随空白(如果有的话)。
[.]
是一个char类,因此您应该添加所有想要查找的"特定字符"。
捕获前两个条件而不捕获第三个条件的正则表达式是('s[.]'s?|'s?[.]'s)
。(同样,您需要用" . "
替换捕获,并将您的"特定字符"添加到char类中。)
然后,您可以选择要使用的正则表达式。