使用preg_match和strlen合并两个字符串

时间:2016-01-29 15:42:11

标签: php regex preg-match strlen

示例文字:

Vind vid marken 
Område 1c: S/15-20 knop, byar upp till 30 knop, efterhand S/15-20 
knop, byar upp till 35 knop. 
Område 1a: S/10-20 knop, efterhand SO/15-20 knop, byar upp till 30 
knop. 
Område 2c,3d: SO/10-15 knop. 
Område 1b: S/15-20 knop, byar upp till 30 knop, efterhand SO/15-20 
knop, byar upp till 30 knop. 
Område 2a,2b,3a,3b,3c: SO/5-10 knop, efterhand SO/10-15 knop. 

我从另一个网页上得到这个文字,我想摆脱第五行" knop。"。 它太短,不会对输出宽度产生任何影响,只会使数据混乱。

我一次遍历每一行,最后回显它。

我以为我可以使用preg_match来查明单词" knop"在NEXT行中,如果NEXT行小于7个字符。 如果这是真的合并他们并继续前进。 我仍在努力使用if(),因此if中的代码可能正确也可能不正确。

if (preg_match("/knop./", $Lines[$i+1]) && 1*strlen($Lines[$i+1] < 7)) {
  echo '<script type="text/javascript">alert("' . 1*strlen($Lines[$i+1]) . '"); </script>';
  echo '<script type="text/javascript">alert("' . 1*strlen($Lines[$i+1]) . '"); </script>';
  echo "<h1>" . $Lines[$i+1] . "</h1>";
  $Lines[$i] = trim($Lines[$i]) . " " .       $Lines[($i+1)]; //                        unset($Lines[($i+1)]); 
}

我只有调试警报和回显H1。 奇怪的是,if会对72个字符长的行做出反应。

我显然做错了什么,我已经想到了......; - )

3 个答案:

答案 0 :(得分:2)

您的正则表达式匹配每个knop和一个附加字符。首先逃避.因为在正则表达式中意味着任何字符。

当前正则表达式的演示:https://regex101.com/r/xQ2eZ3/1

我会制作你的正则表达式:

/^knop\.\h*$/m

检查每一行(因为分隔符后面的m修饰符)。 \s*用于knop.之后的水平空格。

演示:https://regex101.com/r/xQ2eZ3/3

另一种方法可能是在knop.之前检查新行,然后在找到后替换它。还应该检查字符串的开头和结尾。然后可以使用preg_replace

/(?:^|\n)(knop\.\h*(?:\n|$))/

演示:https://regex101.com/r/xQ2eZ3/5

<强>更新

$Result = preg_replace('/\v(knop\.\h*(\v|$))/', '$1', $Lines);
print_r(explode("\n", $Result));

正则表达式演示:https://regex101.com/r/oJ3uB0/1

请注意在爆炸中使用替换值。

PHP演示:https://eval.in/510853

答案 1 :(得分:1)

将整个文本(多行)放在一个字符串中,然后您可以在其上使用此正则表达式来清理它:

// Get all text in one variable first (only needed if you do not have this yet)
$text = implode("\n", $Lines); 
// Move short lines to the end of previous lines
$text = preg_replace('#\h*\R(.{0,2}knop\.)\h*(\R|$)#', " $1\n", $text);
// rebuild Lines variable.
$Lines = explode("\n", $text);

preg_replace 正则表达式和替换的一些解释:

  • 前一行需要\R;
  • 它允许最多两个空闲字符在&#34; knop之前。&#34; (您可以使用此2来允许更多或更少);
  • 它允许在&#34; knop之后出现空格。&#34; \h(水平空格);
  • &#34; knop。&#34;该行必须结束的一些可选空格:\R$(结束)
  • 更换需要注意&#34; knop。&#34;被附加到上一行,它与前一行的最后一个字之间只有一个空格。

请注意,如果echo文本包含\n到浏览器,则不会在这些位置显示换行符,而只会显示一个空格,从而在一个长行中生成输出。要强制浏览器将\n显示为换行符,请将输出包装在pre标记中,如下所示:

echo "<pre>$text</pre>";

答案 2 :(得分:1)

我不知道您发布的结构本身是否代表了您要处理的所有文本,但我看到文本中出现了一种模式。您可以选择尝试通过将“Område”中的字符串连接到第一次完整停止/句点来尝试恢复包装,而不仅仅是检查行中是否只有Pattern pa = Pattern.compile(regex); Matcher m = pa.matcher(expression); while (m.find()) { System.out.println("Method " + m.group("method")); System.out.println("Parameter " + m.group("parameter")); System.out.println("Type" + m.group("type")); } 。这有一个好处,你然后以你认为合适的方式操纵文本。

"knop."

这产生以下结果:

<?php
$text = <<<TEXT
Vind vid marken 
Område 1c: S/15-20 knop, byar upp till 30 knop, efterhand S/15-20 
knop, byar upp till 35 knop. 
Område 1a: S/10-20 knop, efterhand SO/15-20 knop, byar upp till 30 
knop. 
Område 2c,3d: SO/10-15 knop. 
Område 1b: S/15-20 knop, byar upp till 30 knop, efterhand SO/15-20 
knop, byar upp till 30 knop. 
Område 2a,2b,3a,3b,3c: SO/5-10 knop, efterhand SO/10-15 knop. 
I
TEXT;


$new = preg_replace_callback('~(Vind vid marken|(?:Område)(?:[^\.]+))\.~sm', function ($match) {
   // in $match[0], we have the entire line from the occurance of "Område" until a period ".".
   return str_replace(PHP_EOL, '', $match[0]);
}, $text); 


var_dump(wordwrap($new, 80));

这似乎以不同的方式回答了你的问题;)