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-']+~";