Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 正则表达式是否匹配带或不带特殊/重音字符的字符串?_Php_Regex - Fatal编程技术网

Php 正则表达式是否匹配带或不带特殊/重音字符的字符串?

Php 正则表达式是否匹配带或不带特殊/重音字符的字符串?,php,regex,Php,Regex,是否有正则表达式来匹配带有或不带特殊字符的特定字符串?可以说,特殊字符不敏感 Likecéra将匹配cera,反之亦然 有什么想法吗 编辑:我想匹配带有或不带有特殊/重音字符的特定字符串。不仅仅是任何字符串/字符 测试示例: $clientName = 'céra'; $this->search = 'cera'; $compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName)); $thi

是否有正则表达式来匹配带有或不带特殊字符的特定字符串?可以说,特殊字符不敏感

Like
céra
将匹配
cera
,反之亦然

有什么想法吗

编辑:我想匹配带有或不带有特殊/重音字符的特定字符串。不仅仅是任何字符串/字符

测试示例:

$clientName   = 'céra';
$this->search = 'cera';

$compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName));
$this->search      = strtolower($this->search);

if (strpos($compareClientName, $this->search) !== false)
{
    $clientName = preg_replace('/(.*?)('.$this->search.')(.*?)/iu', '$1<span class="highlight">$2</span>$3', $clientName);
}
$clientName='céra';
$this->search='cera';
$compareClientName=strtolower(iconv('utf-8','ascii//TRANSLIT',$clientName));
$this->search=strtolower($this->search);
if(strpos($compareClientName,$this->search)!==false)
{
$clientName=preg_replace('/(.*)('.$this->search')(.*?)/iu'、'$1$2$3'、$clientName);
}
输出:
céra

如您所见,我想突出显示特定的搜索字符串。但是,我仍然希望显示匹配字符串的原始(重音)字符

我想我得想办法把它和其他东西结合起来


我想我必须使用单独的
preg_match()
preg_replace()
,对吗?

您可以使用
\p{L}
模式匹配任何字母

必须在正则表达式之后使用
u
修饰符才能启用unicode模式

示例:
/\p{L}+/u

编辑:

$clientName   = 'céra';
$this->search = 'cera';

$compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName));
$this->search      = strtolower($this->search);

if (strpos($compareClientName, $this->search) !== false)
{
    $clientName = preg_replace('/(.*?)('.$this->search.')(.*?)/iu', '$1<span class="highlight">$2</span>$3', $clientName);
}
试试这样的。它应该将每个字母替换为包含重音字母(单字符和unicode双字符)和非重音字母的搜索模式的重音字母。然后可以使用更正的搜索模式突出显示文本

function mbStringToArray($string)
{
    $strlen = mb_strlen($string);
    while($strlen)
    {
        $array[] = mb_substr($string, 0, 1, "UTF-8");
        $string = mb_substr($string, 1, $strlen, "UTF-8");
        $strlen = mb_strlen($string);
    }
    return $array;
}

// I had to use this ugly function to remove accents as iconv didn't work properly on my test server.
function stripAccents($stripAccents){
    return utf8_encode(strtr(utf8_decode($stripAccents),utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'),'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY'));
}

$clientName = 'céra';

$clientNameNoAccent = stripAccents($clientName);

$clientNameArray = mbStringToArray($clientName);

foreach($clientNameArray as $pos => &$char)
{
    $charNA =$clientNameNoAccent[$pos];
    if($char != $charNA)
    {
        $char = "(?:$char|$charNA|$charNA\p{M})";
    }
}

$clientSearchPattern = implode($clientNameArray); // c(?:é|e|e\p{M})ra

$text = 'the client name is Céra but it could be Cera or céra too.';

$search = preg_replace('/(.*?)(' . $clientSearchPattern . ')(.*?)/iu', '$1<span class="highlight">$2</span>$3', $text);

echo $search; // the client name is <span class="highlight">Céra</span> but it could be <span class="highlight">Cera</span> or <span class="highlight">céra</span> too.
函数mbStringToArray($string)
{
$strlen=mb_strlen($string);
while($strlen)
{
$array[]=mb_substr($string,0,1,“UTF-8”);
$string=mb_substr($string,1,$strlen,“UTF-8”);
$strlen=mb_strlen($string);
}
返回$array;
}
//我不得不使用这个丑陋的功能来删除口音,因为iconv在我的测试服务器上不能正常工作。
函数stripAccents($stripAccents){
返回utf8编码(strtr(utf8解码($stripAccents),utf8解码('á-èèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèè;
}
$clientName='céra';
$clientNameNoAccent=stripAccents($clientName);
$clientNameArray=mbStringToArray($clientName);
foreach($clientNameArray作为$pos=>&$char)
{
$charNA=$clientNameNoAccent[$pos];
如果($char!=$charNA)
{
$char=“(?:$char |$charNA |$charNA\p{M})”;
}
}
$clientSearchPattern=内爆($clientNameArray);//c(?:ée | e\p{M})ra
$text='客户端名称为Céra,但也可以是Cera或Céra';
$search=preg_replace('/(.*)('.$clientSearchPattern.')(.*?/iu','1$2$3',$text);
echo$search;//客户名称是Céra,但也可以是Cera或Céra。

如果您想知道某个字母上是否有重音或其他标记,您可以通过匹配模式来检查它
\p{M}

更新

您需要将模式中的所有重音字母转换为一组备选字母:

例如
céra->c(?:éE|E\p{M})ra

为什么我要添加
e\p{M}
?因为字母e可以是Unicode中的一个字符,也可以是两个字符的组合(e和grave重音)
e\p{M}
匹配带有严重重音的e(两个独立的Unicode字符)

当您转换模式以匹配所有字符时,您可以在
preg\u match

中使用它,正如您所看到的,
POSIX等价类
用于匹配字符,其排序顺序与下面的正则表达式相同:

[=a=]

这将根据您的区域设置匹配
á
ä
以及
a

正如您在其中一条注释中所标记的,您不需要正则表达式,因为目标是查找特定字符串。为什么不使用
分解
?就像这样:

$clientName   = 'céra';
$this->search = 'cera';

$compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName));
$this->search      = strtolower($this->search);

$pieces = explode($compareClientName, $this->search);

if (count($pieces) > 1)
{
    $clientName = implode('<span class="highlight">'.$clientName.'</span>', $pieces);
}
更新2:

$clientName   = 'céra';
$this->search = 'cera';

$compareClientName = strtolower(iconv('utf-8', 'ascii//TRANSLIT', $clientName));
$this->search      = strtolower($this->search);

if (strpos($compareClientName, $this->search) !== false)
{
    $clientName = preg_replace('/(.*?)('.$this->search.')(.*?)/iu', '$1<span class="highlight">$2</span>$3', $clientName);
}
重要的是使用
mb
函数,而不是简单的
strlen
等。这是因为重音字符使用两个或更多字节存储;还要始终确保使用正确的编码,例如:

echo strlen('é');
> 2

echo mb_strlen('é');
> 2

echo mb_internal_encoding();
> ISO-8859-1

echo mb_strlen('é', 'UTF-8');
> 1

mb_internal_encoding('UTF-8');
echo mb_strlen('é');
> 1

é
不是一个特殊的字符,它是一个重音字母。我试图匹配特定的字符串,而不仅仅是任何字符串/字符。很抱歉给你带来了困惑。我更新了我的问题。我也根据@Michael Sivolobov的建议更新了我的答案。OP真的想要匹配任何字母吗?或者在仅指定
e
时匹配
e
,例如?@w3d This。我想匹配带有和不带有特殊(重音)字符的特定字符串。我更新了我的问题。我给出的示例将匹配céra和cera。@Kethryweryn确实如此,但我正在搜索特定字符串。类似于
substr()。据我所知,OP需要一种通用/简单的方法来匹配
c[ée]ra
,但对于任何单词和任何重音,都不太简单。我认为使用字符串位置是唯一简单的方法,可以保持原始字符。我会调查的,谢谢!如果您认为这回答了您的原始问题,请毫不犹豫地将其标记为已接受的答案:)顺便说一句,我添加了另一个更新,涵盖了与多字节字符相关的重要注意事项。我将返回此答案。:)感谢您提供有关
mb
的信息!我目前正在使用,因为它的格式更好,更易于阅读/实现。但是我也要试试你的答案,看看什么最有效。但是POSIX正则表达式语法(以及相关的
ereg()
函数)不是在PHP5.3中就被弃用了吗?@w3d是的,但PCRE甚至支持