【问题标题】:Preg_replace adds unwanted space between ALL charactersPreg_replace 在所有字符之间添加不需要的空格
【发布时间】:2018-01-26 18:45:20
【问题描述】:

我有一个来自 HTML 表格的输入。 首先用'_'替换想要的间距。然后用空格替换 HTML 标记,这样我就可以按列提取信息。

我希望我的输出是:

100 Request_in_progress Pending_response 789653686

Instead the output adds extra spacing like this

$testString = '<tr><td>100</td><td>Request in progress</td><td></td><td></td><td>Pending response</td><td>789653686</td><td></td><td></td><td></td></tr>';
$rmSpace = str_replace(' ', '_', $testString);

$tags = '(<td>||</td>||<tr>||</tr>||<th>||</th>)';
$result = preg_replace($tags, ' ', $rmSpace);

echo $result;

【问题讨论】:

  • 您的正则表达式中有||,它匹配字符串开头/结尾处以及字符串内任何字符之间的任何空字符串。这是一个错字,您应该使用单个|
  • 表达这个正则表达式的更简洁的方式是preg_replace('~&lt;/?t[drh]&gt;~', ' ', $rmSpace);
  • 如果您尝试从 HTML 中获取内容,而不是使用无处不在的正则表达式,请使用 DOMDocumentDOMXPath - 它更简单、更可靠
  • @RamRaider 取决于用例。为了使用一次性脚本从表中抓取一些数据,我每次都会使用正则表达式

标签: php regex html-table preg-replace removing-whitespace


【解决方案1】:

这是因为regex 不正确。

在正则表达式中,the vertical bar (|) 加入替代路径。

表达式&lt;td&gt;||&lt;/td&gt; 的意思是“&lt;td&gt; OR 空字符串 OR &lt;/td&gt;”(等等,但其余的已经无关紧要了)。

因此,您的regex 匹配它包含的所有 HTML 标记,但它也匹配输入字符串中任意两个连续字符之间的空字符串。

正确的regex&lt;td&gt;|&lt;/td&gt;|&lt;tr&gt;|&lt;/tr&gt;|&lt;th&gt;|&lt;/th&gt;

$tags = '#<td>|</td>|<tr>|</tr>|<th>|</th>#';
$result = preg_replace($tags, ' ', $rmSpace);

【讨论】:

    【解决方案2】:

    如何使用简单的DOMDocument 实现此目的的示例

    $testString = '<tr><td>100</td><td>Request in progress</td><td></td><td></td><td>Pending response</td><td>789653686</td><td></td><td></td><td></td></tr>';
    $dom=new DOMDocument;
    $dom->loadHTML( $testString );
    $col=$dom->getElementsByTagName('td');
    $out=array();
    
    if( $col->length > 0 ) foreach( $col as $node )$out[]=str_replace(' ','_',$node->nodeValue);
    
    $out=array_filter($out);
    echo implode(' ',$out);
    

    【讨论】: