从包含PCRE正则表达式的空字段中提取类似CSV的字符串中的值

时间:2016-04-07 14:38:24

标签: regex string csv split pcre

我尝试从多个类似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>

也许我们需要先在另一个组中捕获整个字符串,或者我们需要在另一个组中捕获分号,以便在打印输出后将它们丢弃? ......

2 个答案:

答案 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:            

请参阅https://regex101.com/r/sU2jK5/2

上的演示

答案 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] =>
)

RegEx Demo

并获得所需的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>