我写了下一个正则表达式
$pattern = "~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s-']+~";
为了将子字符串匹配为2.bon jovi - it's my life
问题是唯一被识别的部分是 -bon jovi
这个正则表达式没有识别“ - ”或“'”。
我宁愿知道我写的正则表达式有什么问题,而不是得到一个新的。
一个更好的正则表达式来处理这将是......
$pattern = "~\d+\.\s*[\pL\pP\s]+~";
键盘。
这将匹配一个数字,后跟一个.
,然后是可选的空格,然后是一个或多个 Unicode 字母、空格或标点符号。
您的正则表达式如下。
~ // 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-\']+ //
~ //
“bon”不以大写字母开头,因此不匹配[A-Z]{1}
你可以做一些简单的事情来清理你的正则表达式
{1}
它与不存在相同将上述内容应用于您现有的正则表达式,您将获得:
$pattern = "~\d+\.\s*[A-Z][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 ( http://gskinner.com/RegExr/ ) 上快速测试了它,它似乎与字符串匹配得很好。
您的正则表达式指出,在句点字符(可以更改为\.
)之后,您将有零个或多个空格字符,然后应后跟 1 个大写字母。在您的字符串中,您没有任何大写字母。
其次,-
当你想匹配它时,应该放在最后。因此,将您的正则表达式更改为:~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s'-]+~
将匹配如下内容:2.Bon jovi - it's my life
。
另一方面,您可以将其更改为:~\d+[.][\s]*[A-Za-z0-9\s'-]+~
以匹配如下内容:2.bon jovi - it's my life
。
编辑:根据 Marko D 和 aleation 的评论进行了修改。
$pattern = "~\d+\..*~";
$string = "2.bon jovi - it's my life";
preg_match($pattern, $string, $match);
print_r($match);
输出:数组([0] => 2.bon jovi - 这是我的生活)
您的[A-Z]{1}
子模式需要一个大写字母,因此"2.bon jovi - it's my life"
不匹配。
而且你需要-
在[A-Za-z0-9\s-']
字符类中转义,或者把它放在开头或结尾,否则它指定了一个范围。
"~\d+\.[A-Za-z0-9\s'-]+~"
正如评论中所指出的,实际上没有必要-
在您的正则表达式中转义字符类中的 。那只是因为您碰巧在它前面加上了一个\s
不能成为范围一部分的元字符。通常,如果你想匹配一个文字-
并且你有一个字符类,你必须像上面描述的那样对其进行转义或定位。