我尝试从多个类似csv的简单数据列字符串中捕获包含(!)空列的列的值,并用分号分隔。即使我知道正则表达式不是最好的方法,显式csv解析器也会做得更好,在这种情况下,除了使用PRCE正则表达式构建html表flightlegid
组之外别无选择这个数据。
应该(仍然)工作的恶化例子看起来像这样:
<td>
......应按字面解释:
;testvalue;"testvalue";"test "val"ue";test value;
...最终被渲染到这里(不是问题的一部分):
empty | testvalue | testvalue | test "val"ue | test value | empty
(像@anubhava一样更新)
可悲的是还有另外一个 downer :它将实现的系统有一个固定的方式来处理字符串。它只会识别并且只能更改捕获的字符串组。字符串的任何其他未注册部分将直接打印出来,其余 as as is 。这意味着:我们需要注册正则表达式中的分号,即使我们不希望它们被打印出来,也可以通过忽略它们的匹配组来删除它们。
通常,只打印出捕获的组就足够了,但这不适用于此。要仅捕获值,将导致此输出:
<td>empty</td>
<td>testvalue</td>
<td>testvalue</td>
<td>test"val"ue</td>
<td>test value</td>
<td>empty</td>
也许我们需要先在另一个组中捕获整个字符串,或者我们需要在另一个组中捕获分号,以便在打印输出后将它们丢弃? ......
答案 0 :(得分:2)
尝试关注PCRE正则表达式:
\"(?:.*?)\"(?=;|$)|(?<=(?:;))(?:.*?)(?=;|$)|^(?:[^;]*?)(?=;)
从样本字符串;testvalue;"testvalue";"test value";test value;
开始,正则表达式将捕获:
Match 1:
Match 2: testvalue
Match 3: "testvalue"
Match 4: "test value"
Match 5: test value
Match 6:
上的演示
答案 1 :(得分:2)
你可以使用这个更简单的正则表达式,并在第三个捕获组中使用包含分号的lookbehind:
$str = ';testvalue;"testvalue";"test "val"ue";test value;';
preg_match_all('/(?<=;|^)("?)([^;]*)\1(;|$)/', $str, $matches);
print_r($matches[2]);
(?<=;|^)
是一个积极的观察背后,以确保我们只在行开始后或[^;]*
匹配;
。
<强>输出:强>
Array
(
[0] =>
[1] => testvalue
[2] => testvalue
[3] => test "val"ue
[4] => test value
[5] =>
)
并获得所需的HTML:
echo "<td>" . implode("</td>\n<td>", $matches[2]) . "</td>\n";
<td></td>
<td>testvalue</td>
<td>testvalue</td>
<td>test "val"ue</td>
<td>test value</td>
<td></td>