PHP正则表达式与所需的子字符串不匹配

PHP正则表达式与所需的子字符串不匹配,php,regex,Php,Regex,我已经编写了下一个正则表达式 $pattern = "~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s-']+~"; 为了将子字符串匹配为2.bon jovi-这是我的生活 问题是唯一被识别的部分是-bon jovi 此正则表达式不识别“-”或“%” 我宁愿知道我写的正则表达式有什么问题,也不愿得到一个新的。更好的正则表达式是 $pattern = "~\d+\.\s*[\pL\pP\s]+~"; 这将匹配一个数字,后跟一个,后跟可选的空格,后跟一个或多个Unicode字母

我已经编写了下一个正则表达式

$pattern = "~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s-']+~";
为了将子字符串匹配为
2.bon jovi-这是我的生活

问题是唯一被识别的部分是-
bon jovi
此正则表达式不识别“-”或“%”


我宁愿知道我写的正则表达式有什么问题,也不愿得到一个新的。

更好的正则表达式是

$pattern = "~\d+\.\s*[\pL\pP\s]+~";


这将匹配一个数字,后跟一个
,后跟可选的空格,后跟一个或多个Unicode字母、空格或标点符号。

正则表达式声明在句点字符之后(可以更改为
\。
),您将有零个或多个空格字符,这些字符后面应该跟一个大写字母。在字符串中,没有任何大写字母

其次,
-
应该放在最后,当您想要匹配它时。因此,将正则表达式更改为:
~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s'-]+~
将匹配如下内容:
2.Bon jovi-这是我的生活

另一方面,您可以将其更改为:
~\d+[.][\s]*[A-Za-z0-9\s'-]+~
以匹配这样的内容:
2.bon jovi-这是我的生活


编辑:根据Marko D和aleation的评论进行编辑。

您的
[A-Z]{1}
子模式需要一个大写字母,因此
“2.bon jovi-这是我的生活”
将不匹配

您需要转义
[A-Za-z0-9\s-']
字符类中的
-
,或者将其放在开头或结尾,否则它将指定一个范围

"~\d+\.[A-Za-z0-9\s'-]+~"
正如注释中指出的,实际上没有必要在正则表达式的字符类中转义
-
。这只是因为您碰巧在它前面加了一个不能作为范围一部分的元字符
\s
。通常,如果要匹配文字
-
,并且将其放在字符类中,则必须按照上述说明对其进行转义或定位

$pattern = "~\d+\..*~";    
$string = "2.bon jovi - it's my life";
preg_match($pattern, $string, $match);

print_r($match);

输出:数组([0]=>2.bon jovi-这是我的生命)

您的regrex如下所示

~                 // delimiter
\d+               // 1 or more numbers
[.]               // a period
[\s]*             // 0 or more whitespace characters
[A-Z]{1}          // 1 upper case letter
[A-Za-z0-9\s-\']+ // 1 or more characters, from the character class
~                 //delimiter
将其与字符串“2.bon jovi”进行比较:

~                 //
\d+               // "2"
[.]               // "."
[\s]*             // ""
[A-Z]{1}          // <- NO MATCH
[A-Za-z0-9\s-\']+ // 
~                 // 

更容易阅读。

所以我理解这个正则表达式的方式是:

\d+      // Match any digit, 1 or more times  
[.]      // Match a dot  
[\s]*    // Match 0 or more whitespace characters  
[A-Z]{1} // Match characters between an UPPERCASE A-Z Range 1 time  
[A-Za-z0-9\s-']+ // Match characters between A-Z, a-z, 0-9, whitespace, dashe and apostrophe
因此,您的“bon jovi”可能无法匹配,因为它是小写,而您只查找大写字符。”bon jovi'还包含一个空格,因此可能需要更改正则表达式的该部分以允许使用小写字符和空格,这样您就可以得到:

$pattern = "~\d+[.][\s]*[A-Za-z\s]{1}[A-Za-z0-9\s-']+~";

注意:我很快在RegExr()上测试了它,它似乎与字符串匹配得很好。

~
是phpin PCRE中的一个,您需要分隔符。通常他们使用“/pattern/”,但实际上你可以使用你想要的任何东西确切地说,你需要什么,从哪里得到子字符串?你永远不必使用
{1}
,这意味着
[.]//任何单个字符
-->不。在PCRE的
[A-Za-z0-9\s-']
情况下,它与文本
匹配
-
被解释为文本
-
。在这种情况下,不必转义
-
,但我们通常这样做只是为了确保。最好是在为相同语言编写的测试仪中测试正则表达式。(RegExr是ActionScript 3 regex)。在大多数情况下,结果都是一样的,但不同的实现中可能存在不兼容性,这需要正确的测试人员来揭示。
$pattern = "~\d+[.][\s]*[A-Za-z\s]{1}[A-Za-z0-9\s-']+~";