‘壹’ php正则表达式求教,在线等,日期提取
1, 一种是使用以下正则, 取得三个分组, 再将三个分组合并
(d{4})-(d{2})-(d{2})
'aabbccc2016-07-31cccddd99.88eee77.66ffff'.replace(/.*?(d{4})-(d{2})-(d{2}).*/,function(x,a,b,c){returna+b+c})
‘贰’ PHP中正则问题
首先赞扬一下楼主的提问方式:
1. 对问题描述得很清晰;
2. 给出了匹配的范例文本;
3. 指定了正则式所在的语言。
这才应该是规范合理的提问。
言归正传,先根据问题,写出正则,然后落实到PHP语言。如果对分析过程不感兴趣,请直接pagedown看答案。
1. 基础
需要匹配的关键词为:test,你好,程序,分类。
正则表达式:/test|你好|程序|分类/i
(i是表示大小写不敏感模式。如果指定匹配小写的test,则可以去掉i)
2. 限制条件
a. 不在标签内部,例如<img src=asdasda.jpg alt="test" title="你好">,里面虽然有test和你好,但这不满足要求;
b. 本身无链接。例如,<a href="link1" alt="程序设计">程序设计</a>中,>程序设计<中的程序由于处于<a..>程序设计</a>之间,同样不满足要求。
根据以上限制,写出纯粹的正则式(并不能直接用在php中):
(?<!<(?:a|img)[^<>]*)(test|你好|程序|分类)(?![^<>]*</a>)
它表示,(test|你好|程序|分类)的紧临左侧不能出现<a..标签,或者<img标签;紧临右侧不能出现</a>标签。
“紧临”二字至关重要,它将无直接关系的<>都忽略掉,才确保条件的正确执行。怎样实现这一点呢?我使用的是[^<>]*。
正则式的部分这里就交待清楚了。下面将正则式应用到PHP中。
3. php正则式
php使用的正则表达式是PCRE的,它不支持在lookbehind里使用无限量词,即(?<!<(?:a|img)[^<>]*)部分不被PCRE支持。没关系,可以修改之。
(?<!(?:<a|<img))([^<>]*)(test|你好|程序|分类)(?![^<>]*(?:>|</a>))
与2中的正则式相比,前者$1即为所求,其余部分只匹配,不消耗字符;而后者$2为所求,还需要对$1进行处理。
4. php细节
我使用preg_replace_callback函数,以便自定义替换过程。代码如下,随手注释:
<?php
//此处使用heredoc语法,以便支持复杂的长文本。
$x=<<<EOT
请从以下推荐分类中选择合适的分类:<br>电脑/网络 -> <a href="link1" alt="程序设计">程序设计</a><br>
电脑/网络 -> 操作系统/系统故障<br>
<br>
如果没有合适的推荐分类,建议您更改分类,有助于获得准确解答 <br>
<img src=asdasda.jpg alt="test" title="你好"><br>
您还可以输入1381字<br>
test<br>
输入内容已经达到长度限制<br>
EOT;
//关键词数组
$a=array(
1 => "test",
2 => "你好",
3 => "程序" ,
4 => "分类"
);
//记号数组,用于记录哪些匹配是已经替换了的。因为楼主指定“每个词只匹配一次”。
$index=array();
function compute_replacement($groups) {
global $a;
global $index;
if ($index[$groups[2]])
{
//如果该关键词已经被处理过,那么直接返回整个字串($groups[0]),不作处理。
return $groups[0];
}
//查询该关键词在数组中的位置,确定序号,以便生成href="1.html"之类链接地址。
$in=array_search($groups[2],$a);
//将处理过的关键词标记为已处理,避免重复。
$index[$groups[2]]=1;
//返回处理好的文本。
return "$groups[1]<a href=\"$in.html\" title=\"$groups[2]\">$groups[2]</a>";
}
$r= preg_replace_callback('%(?<!<)([^<>]*)(test|你好|程序|分类)(?![^<>]*(?:>|</a>))%s', compute_replacement, $x);
echo $r;
?>
输出的结果为:
请从以下推荐分类中选择合适的<a href="4.html" title="分类">分类</a>:<br>电脑/网络 -> <a href="link1" alt="程序设计">程序设计</a><br>
电脑/网络 -> 操作系统/系统故障<br>
<br>
如果没有合适的推荐分类,建议您更改分类,有助于获得准确解答 <br>
<img src="asdasda.jpg" alt="test" title="你好"><br>
您还可以输入1381字<br>
<a href="1.html" title="test">test</a><br>
输入内容已经达到长度限制<br></body>
注:这里的格式不好,建议去“参考资料”所指向的地址察看更易读版本的解答。
正则表达式论坛:
正则表达式博客:
附:匹配图。高亮部分为匹配结果。
‘叁’ PHP正则问题
/<img(.*?)src="(.+?)"\szoomfile="(.+?)"(.*?)width="(.*?)".+?\/>/
你忘了width后面的东西了。
‘肆’ php 正则表达式选出来的东西怎么分组
你这个正则有错误, 你这个匹配的是<img然后所有都行然后>结尾, 那么,这种匹配方式,得到的就不一定是:<img src="">了, 他可以是<img src=""><img src="">。。。。等等
所有呢,应该改一下, /\<img([^>]*)\>/
‘伍’ PHP正则表达式中分组的提取
我也不懂,你先用 /[AQI:(.*?)]/ /\[AQI:(.*?)\]/试试
或 /\[AQI:(.*?)\]/s
‘陆’ 请教PHP正则
?: 是个整体,这个意思是外面的括号仅仅起分组的作用,匹配结果不出现在 $1 $2 $3 ... 里面。
\+? 中的 ? 匹配0个至1个 +
(...)? 的 ? 同上,匹配括号中的内容0次到1次
补充:
通常情况下,正则表达式的()可以将匹配结果提取出来。
比如/^(\d+)-(\d+)-(\d+)$/ 这样的表达式可以匹配 "2010-03-01" 这样的字符串,执行匹配之后会将结果放在 $1 $2 $3 里面,$1的内容是2010, $2的内容是03,$3的内容是01。
括号里面开头加 ?: 就是跳过这个括号,也就是不提取其中内容,仅仅起分组的作用。如果用/^(?:\d+)-(\d+)-(\d+)$/ 匹配 "2010-03-01",$1的内容就是03,而不是2010了。
可以用以下程序验证:
<?php
preg_match('/^(\d+)-(\d+)-(\d+)$/', '2010-03-01', $matches);
print_r($matches);
preg_match('/^(?:\d+)-(\d+)-(\d+)$/', '2010-03-01', $matches);
print_r($matches);
‘柒’ /^(0|[1-9]\d*)([.]5)$/ 在PHP正则中是什么意思
这个正则:匹配非负整数和非负整数加上0.5(即:xxx.5);
鉴于你给这么多分,详细来讲讲哈:
^ 匹配开头,$匹配结尾,意味着匹配的字符串,必须最多只能是数字和".5"组成,不能包含其他字符。
()是分组,| 是或者的意思,\d*这个表示0-9,第一个括号里面的意思是,字符串为0,或者1-9里面的任意数字,加上0-9组成的任意位数的数字,即一个正整数。
第二个括号,[.],这里面只有1个'.',等价于'\.',即小数点;后面的5就是数字5;最后加个问号,代表后面的".5"是可选的,可以不要。
总结:上面的正则能匹配:0,1,2,3,0.5,1.5,999,999.5这些类型的数字字符串。
有不明白的,欢迎继续追问。
‘捌’ PHP正则表达式((:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is是什么意思
(?: )表示只进行分组,不进行捕获
[0-9a-zA-Z$_.`-] ——0-9、a-z、A-Z或$、_、.、`、-中的一个字符
| ——表示或者
[\xC2-\xDF][\x80-\xBF] ——用十六进制表示的字符范围【具体是什么字符不太清楚,比如汉字的范围一般是 4E00-9FA5】
+ ——前面的字符有一个或多个
(?: +) 外面的括号( )——是捕获括号。即不捕获单个匹配字符,只捕获匹配的最大字串。
/is——是PHP中正则表达式模式修饰符,其中i代表 不区分大小写,s代表:如果设定了这个修正符,那么,被匹配的字符串将视为一行来看,包括换行符,换行符将被视为普通字符串。
模式修饰符还有:m、x、e等
‘玖’ PHP正则表达式分组为什么可这样实现
preg_replace 和str_replace 这两个的意思你可以去了解一下就明白了。