我试图在preg_match的帮助下在PHP中搜索一些模式。搜索模式是这样的(但这是错误的):
/[\d\s*-\s*\d\s*(usd|eur)]{1}/i
\d starts with integer,
\s* there can be any number of whitespaces,
- there must be exactly one minus sign
\s* there can be any number of whitespaces,
\d then must be integer
\s* there can be any number of whitespaces,
(usd|eur) any of the following words must be present but one
[\d\s*-\s*\d\s*(usd|eur)]{1} - in string there should be exactly one occurence
上面的模式不起作用,我做错了什么?测试:
<?php
$pattern = '/[\d\s*-\s*\d\s*(usd|eur)]{1}/i';
$query = '100-120 100-120';
echo $pattern.'<br/>';
echo $query.'<br/>';
if(preg_match($pattern, $query))
echo 'OK';
else
echo 'not OK!';
?>
注意: 我试图提取这样的数据:
The price of item is 100 - 120 usd in our market
答案 0 :(得分:2)
[...]
是一个字符类。这意味着“匹配这些角色中的任何一个”。 [abc]
将匹配a,b,或 c。它与字符串“abc”不匹配。
另外:
{1}
表示“匹配前面的表达式一次”。但是,匹配一次是默认值。没有必要明确告诉它匹配一次。
\d
匹配单个数字。根据您的示例,您需要\d+
- 匹配由至少一位数组成的数字。
以下是您的模式应该是什么样的:
/\d+\s*-\s*\d+\s*(usd|eur)/i
答案 1 :(得分:1)
正则表达式是检查和修改文本的强大工具。正则表达式本身,通常的模式符号几乎像一个迷你编程语言,允许您描述和解析文本。它们使您能够在字符串中搜索模式,灵活且精确地提取匹配。但是,您应该注意,因为正则表达式更强大,它们也比更基本的字符串函数慢。如果您有特殊需要,则应该只使用正则表达式。
本教程简要概述了基本的正则表达式语法,然后考虑了PHP为正则表达式提供的函数。
The Basics
Matching Patterns
Replacing Patterns
Array Processing
PHP支持两种不同类型的正则表达式:POSIX-extended和Perl-Compatible Regular Expressions(PCRE)。 PCRE功能比POSIX功能更强大,也更快,所以我们将专注于它们。
基础知识
在正则表达式中,大多数字符仅与自身匹配。例如,如果你搜索正则表达式&#34; foo&#34;在字符串&#34;约翰踢足球,&#34;你得到了一场比赛因为&#34; foo&#34;发生在该字符串中。某些字符在正则表达式中具有特殊含义。例如,美元符号($)用于匹配以给定模式结束的字符串。类似地,正则表达式开头的插入符号(^)表示它必须与字符串的开头匹配。与自身匹配的字符称为文字。具有特殊含义的字符称为元字符。
点(。)元字符匹配除换行符()之外的任何单个字符。因此,模式h.t匹配hat,hothit,hut,h7t等。垂直管道(|)元字符用于正则表达式中的替代。它的行为很像逻辑OR运算符,如果要构造匹配多个字符集的模式,则应使用它。例如,模式犹他州|爱达荷州|内华达州匹配包含&#34;犹他州&#34;或&#34; Idaho&#34;或&#34;内华达&#34;。括号为我们提供了一种分组序列的方法。例如,(Nant | b)ucket匹配&#34; Nantucket&#34;或&#34;桶&#34;。使用括号将字符组合在一起进行交替称为分组。
如果要匹配模式中的文字元字符,则必须使用反斜杠对其进行转义。
要在模式中指定一组可接受的字符,您可以自己构建一个字符类,也可以使用预定义的字符类。字符类允许您将一堆字符表示为正则表达式中的单个项目。您可以通过将可接受的字符括在方括号中来构建自己的字符类。字符类匹配类中的任何一个字符。例如,字符类[abc]匹配a,b或c。要定义一系列字符,只需将第一个和最后一个字符放入,用连字符分隔。例如,要匹配所有字母数字字符:[a-zA-Z0-9]。您还可以创建一个否定的字符类,它匹配类中没有的任何字符。要创建否定的字符类,请使用^:[^ 0-9]开始字符类。
元字符+,*,?和{}会影响模式匹配的次数。 +表示&#34;匹配上述表达式中的一个或多个&#34;,*表示&#34;匹配前面表达式中的零个或多个&#34;,和?表示&#34;匹配前面的表达式中的零个或一个&#34;。可以使用不同的曲线括号{}。对于单个整数,{n}表示&#34;恰好匹配前面的表达式&#34;恰好n次出现,带有一个整数和一个逗号,{n,}表示&#34;匹配前面表达式的n次或多次出现& #34;和两个以逗号分隔的整数{n,m}表示&#34;匹配前一个字符,如果它至少出现n次,但不超过m次&#34;。
现在,看看这些例子:
Regular Expression Will match...
foo The string "foo"
^foo "foo" at the start of a string
foo$ "foo" at the end of a string
^foo$ "foo" when it is alone on a string
[abc] a, b, or c
[a-z] Any lowercase letter
[^A-Z] Any character that is not a uppercase letter
(gif|jpg) Matches either "gif" or "jpeg"
[a-z]+ One or more lowercase letters
[0-9\.\-] Аny number, dot, or minus sign
^[a-zA-Z0-9_]{1,}$ Any word of at least one letter, number or _
([wx])([yz]) wy, wz, xy, or xz
[^A-Za-z0-9] Any symbol (not a number or a letter)
([A-Z]{3}|[0-9]{4}) Matches three letters or four numbers
Perl兼容的正则表达式模拟模式的Perl语法,这意味着每个模式必须包含在一对分隔符中。通常,使用斜杠(/)字符。例如,/ pattern /.
PCRE功能可分为几类:匹配,替换,拆分和过滤。
匹配模式
preg_match()函数对字符串执行Perl样式的模式匹配。 preg_match()有两个基本参数和三个可选参数。这些参数依次是正则表达式字符串,源字符串,存储匹配的数组变量,标志参数和偏移参数,可用于指定开始搜索的备用位置: preg_match(pattern,subject [,matches [,flags [,offset]]])
如果找到匹配,则preg_match()函数返回1,否则返回0。让我们搜索字符串&#34; Hello World!&#34;对于字母&#34; ll&#34;:
<?php
if (preg_match("/ell/", "Hello World!", $matches)) {
echo "Match was found <br />";
echo $matches[0];
}
?>
字母&#34; ll&#34;存在于&#34; Hello&#34;中,因此preg_match()返回1并且$ matches变量的第一个元素填充了与模式匹配的字符串。下一个例子中的正则表达式是查找字母&#34; ell&#34;,但是用以下字符查找它们:
<?php
if (preg_match("/ll.*/", "The History of Halloween", $matches)) {
echo "Match was found <br />";
echo $matches[0];
}
?>
现在让我们考虑更复杂的例子。最常用的正则表达式是验证。下面的示例检查密码是否为“#34;”,即密码必须至少为8个字符,且必须至少包含一个小写字母,一个大写字母和一个数字:
<?php
$password = "Fyfjk34sdfjfsjq7";
if (preg_match("/^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/", $password)) {
echo "Your passwords is strong.";
} else {
echo "Your password is weak.";
}
?>
^和$正在寻找字符串开头和结尾的东西。 &#34;。*&#34;组合在开始和结束时使用。如上所述,。(点)元字符表示任何字母数字字符,*元字符表示&#34;零或更多&#34;。之间是括号中的分组。 &#34;?=&#34;组合意味着&#34;下一个文本必须是这样的&#34;。此构造不捕获文本。在这个例子中,不是指定事物应该出现的顺序,而是说它必须出现,但我们并不担心订单。
第一个分组是(?=。 {8,})。这将检查字符串中是否至少包含8个字符。下一个分组(?=。 [0-9])表示&#34;任何字母数字字符可以发生零次或多次,然后任何数字都可能发生&#34;。因此,这将检查字符串中是否至少有一个数字。但由于字符串未被捕获,因此该字符串中的任何一个都可以出现。下一个分组(?=。 [a-z])和(?=。 [A-Z])相应地在字符串中的任何位置查找小写字母和大写字母。
最后,我们将考虑验证电子邮件地址的正则表达式:
<?php
$email = firstname.lastname@aaa.bbb.com;
$regexp = "/^[^0-9][A-z0-9_]+([.][A-z0-9_]+)*[@][A-z0-9_]+([.][A-z0-9_]+)*[.][A-z]{2,4}$/";
if (preg_match($regexp, $email)) {
echo "Email address is valid.";
} else {
echo "Email address is <u>not</u> valid.";
}
?>
此正则表达式检查开头的数字,并检查电子邮件地址中的用户名和域名中的多个句点。让我们自己尝试调查这个正则表达式。
出于速度原因,preg_match()函数仅匹配它在字符串中找到的第一个模式。这意味着可以非常快速地检查字符串中是否存在模式。另一个函数preg_match_all(),将模式与字符串匹配的次数与模式允许的次数相同,并返回匹配的次数。
替换模式
在上面的例子中,我们搜索了字符串中的模式,保持搜索字符串不变。 preg_replace()函数查找与模式匹配的子字符串,然后用新文本替换它们。 preg_replace()有三个基本参数和一个额外参数。这些参数依次是正则表达式,用于替换找到的模式的文本,要修改的字符串,以及指定将替换多少匹配的最后一个可选参数。 preg_replace(模式,替换,主题[,限制])
如果找到匹配项,函数将返回更改后的字符串,否则返回原始字符串的未更改副本。在下面的示例中,我们搜索版权短语并将当前年份替换为当前。
<?php
echo preg_replace("/([Cc]opyright) 200(3|4|5|6)/", "$1 2007", "Copyright 2005");
?>
在上面的例子中,我们在替换字符串中使用了后引用。返回引用使您可以在替换字符串中使用匹配模式的一部分。要使用此功能,您应该使用括号来包装您可能想要使用的正则表达式的任何元素。您可以使用美元符号($)和子模式的编号来引用子模式匹配的文本。例如,如果您使用子模式,则将$ 0设置为整个匹配,然后将$ 1,$ 2等设置为每个子模式的各个匹配项。
在下面的示例中,我们将更改日期格式为&#34; yyyy-mm-dd&#34;到&#34; mm / dd / yyy&#34;:
<?php
echo preg_replace("/(\d+)-(\d+)-(\d+)/", "$2/$3/$1", "2007-01-25");
?>
我们还可以传递一个字符串数组作为主题,以便对所有字符串进行替换。要通过调用preg_replace()对同一个字符串或字符串数组执行多次替换,我们应该传递模式和替换的数组。看看这个例子:
<?php
$search = array ( "/(\w{6}\s\(w{2})\s(\w+)/e",
"/(\d{4})-(\d{2})-(\d{2})\s(\d{2}:\d{2}:\d{2})/");
$replace = array ('"$1 ".strtoupper("$2")',
"$3/$2/$1 $4");
$string = "Posted by John | 2007-02-15 02:43:41";
echo preg_replace($search, $replace, $string);?>
在上面的例子中,我们使用了其他有趣的功能 - 你可以对PHP说,匹配文本应该在替换发生后作为PHP代码执行。因为我们附加了一个&#34; e&#34;到正则表达式结束时,PHP将执行它所做的替换。也就是说,它将使用strtoupper(name)并将其替换为strtoupper()函数的结果,即nAME。
数组处理
PHP的preg_split()函数使您能够基于比文字字符序列更复杂的东西来区分字符串。如果需要使用动态表达式而不是固定表达式来分割字符串,则可以使用此功能。基本思想与preg_match_all()相同,不同之处在于,它不返回主题字符串的匹配片段,而是返回与指定模式不匹配的片段数组。以下示例使用正则表达式将字符串拆分为任意数量的逗号或空格字符:
<?php
$keywords = preg_split("/[\s,]+/", "php, regular expressions");
print_r( $keywords );
?>
另一个有用的PHP函数是preg_grep()函数,它返回与给定模式匹配的数组元素。此函数遍历输入数组,根据提供的模式测试所有元素。如果找到匹配项,匹配元素将作为包含所有匹配项的数组的一部分返回。以下示例搜索数组,所有名称以字母A-J开头:
<?php
$names = array('Andrew','John','Peter','Nastin','Bill');
$output = preg_grep('/^[a-m]/i', $names);
print_r( $output );
?>