时间:2021-10-11
问题: 正则表达式连续使用 .*? 时导致前面的部分匹配规则失效。
原因:
连着使用 .*? 时,中间没有一个明确提示惰性匹配结束的字符,让它知道在哪可以停下来,否则直接进入下一个 .*? 后,前面的 .*? 即使啥也不匹配就已经符合规则了
解决方法:
连续使用 .*? 时,在进入下一个 .*? 前, 每一个 .*? 后面应该至少有一个明确提示惰性匹配结束的字符,让它知道这个 .*? 是应该在哪停下来。
截图
测试代码
public function dealHtmlOfTable()
{
$table_str = '"<table cellspacing="1"><tbody><tr style="font-weight: bold; color: red;" class="firstRow"><th colspan="2">加盟城市</th><th>一线城市</th><th>二线城市</th><th>三线城市</th></tr><tr><td colspan="2">店铺面积</td><td>100㎡</td><td>90㎡</td><td>80㎡</td></tr><tr><td rowspan="5">北欧时光加盟基础费用</td><td>装修费</td><td>8万元(800元/㎡*100㎡)</td><td>6.3万元(700元/㎡*90㎡)</td><td>4.8万元(600元/㎡*80㎡)</td></tr><tr><td>设备费</td><td>6万元</td><td>5万元</td><td>4.5万元</td></tr><tr><td>进货费/原料费</td><td>1.5万元</td><td>1.2万元</td><td>1万元</td></tr><tr><td>广告宣传及开业费</td><td>8000元</td><td>7000元</td><td>6000元</td></tr><tr><td>小计</td><td>16.3万元</td><td>13.2万元</td><td>10.9万元</td></tr><tr><td rowspan="5">北欧时光加盟成本费用</td><td>店面租金</td><td>1.5万元/月(5元/天/㎡)</td><td>1.3万元/月(4.8元/天/㎡)</td><td>1.08万元/月(4.5元/天/㎡)</td></tr><tr><td>人员工资</td><td>1.4万元/月(3500元/月/人*4人)</td><td>1.2万元/月(3000元/月/人*4人)</td><td>1万元/月(2500元/月/人*4人)</td></tr><tr><td>水电杂费</td><td>1500元</td><td>1400元</td><td>1300元</td></tr><tr><td>流动资金</td><td>8.7万元</td><td>7.49万元</td><td>6.24万元</td></tr><tr><td>小计</td><td>11.75万元</td><td>10.13万元</td><td>8.45万元</td></tr><tr><td>北欧时光加盟总费用</td><td>投资合计</td><td>28.05万元</td><td>23.33万元</td><td>19.35万元</td></tr><tr><td rowspan="9">北欧时光加盟利润</td><td>人均消费</td><td>22元</td><td>20元</td><td>18元</td></tr><tr><td>日客流量</td><td>140人</td><td>130人</td><td>120人</td></tr><tr><td>日营业额</td><td>3080元</td><td>2600元</td><td>2160元</td></tr><tr><td>月营业额</td><td>9.24万元</td><td>7.8万元</td><td>6.48万元</td></tr><tr><td>毛利率</td><td>55%</td><td>55%</td><td>55%</td></tr><tr><td>毛利润(月)</td><td>5.08万元</td><td>4.29万元</td><td>3.56万元</td></tr><tr><td>减成本费用</td><td>3.05万元</td><td>2.636万元</td><td>2.21万元</td></tr><tr><td>净利润(月)</td><td>2.03万元</td><td>1.65万元</td><td>1.35万元</td></tr><tr><td>净利润(年)</td><td>24.38万元</td><td>19.85万元</td><td>16.25万元</td></tr><tr><td colspan="2">投资回报周期</td><td>9个月</td><td>8个月</td><td>9个月</td></tr></tbody></table>"';
if (empty($table_str)) {
return '';
}
//表格添加外边框,设置合并每个单元边框,设置字体为12px,
$table_str = preg_replace_callback('/(\<table.*?)( style=[\'"])*(.*?\>)/s', function ($matches) {
$table_style1 = ' style="border-collapse: collapse; border: 1px solid #666; font-size: 12px;" ';
$table_style2 = 'border-collapse: collapse; border: 1px solid #666; font-size: 12px;';
if (empty($matches[2])) {
return $matches[1] . $table_style1 . $matches[3];
} else {
return $matches[1] . $matches[2] . $table_style2 . $matches[3];
}
}, $table_str);
//设置th的边框
$table_str = preg_replace_callback('/(\<th.*?)( style=[\'"])*(.*?\>)/s', function ($matches) {
$th_border1 = ' style="border: 1px solid #666;" ';
$th_border2 = 'border: 1px solid #666;';
if (empty($matches[2])) {
return $matches[1] . $th_border1 . $matches[3];
} else {
return $matches[1] . $matches[2] . $th_border2 . $matches[3];
}
}, $table_str);
//设置td的边框
$table_str = preg_replace_callback('/(\<td.*?)( style=[\'"])*(.*?\>)/s', function ($matches) {
$td_border1 = ' style="border: 1px solid #666;" ';
$td_border2 = 'border: 1px solid #666;';
if (preg_match('/rowspan=[\'"]/', $matches[1]) || preg_match('/rowspan=[\'"]/', $matches[3])) {
//td(一个单元格)占据多行, 背景色统一设置为 background-color: rgb(255, 255, 255);
$td_border1 = ' style="background-color: rgb(255, 255, 255); border: 1px solid #666;" ';
$td_border2 = 'background-color: rgb(255, 255, 255); border: 1px solid #666;';
}
if (empty($matches[2])) {
return $matches[1] . $td_border1 . $matches[3];
} else {
return $matches[1] . $matches[2] . $td_border2 . $matches[3];
}
}, $table_str);
//隔行设置灰色
$table_str = preg_replace_callback('/(\<tr.*?)( style=[\'"])*(.*?\>)/s', function ($matches) {
$tr_bg1 = ' style="background-color: rgb(231, 231, 231);" ';
$tr_bg2 = ' style="background-color: rgb(255, 255, 255);" ';
$tr_bg3 = 'background-color: rgb(231, 231, 231);';
$tr_bg4 = 'background-color: rgb(255, 255, 255);';
static $tr_num = 1;
if (empty($matches[2])) {
if ($tr_num % 2 == 1) {
$tr_bg = $tr_bg1;
} else {
$tr_bg = $tr_bg2;
}
$tr_num++;
return $matches[1] . $tr_bg . $matches[3];
} else {
if ($tr_num % 2 == 1) {
$tr_bg = $tr_bg3;
} else {
$tr_bg = $tr_bg4;
}
$tr_num++;
return $matches[1] . $matches[2] . $tr_bg . $matches[3];
}
}, $table_str);
return $table_str;
}