使用 preg_match 和 strlen 合并两个字符串
Merge two strings with preg_match and 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" 是否在下一行以及下一行是否少于 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 个字符长的行作出反应。
我显然做错了什么,我已经弄清楚了...;-)
您的正则表达式匹配每个 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|$))/', '', $Lines);
print_r(explode("\n", $Result));
正则表达式演示:https://regex101.com/r/oJ3uB0/1
还要注意分解中替换值的用法。
PHP 演示:https://eval.in/510853
将整个文本(多行)放在一个字符串中,然后你可以在上面使用这个正则表达式来清理它:
// 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|$)#', " \n", $text);
// rebuild Lines variable.
$Lines = explode("\n", $text);
preg_replace正则表达式和替换的一些解释:
- 需要前一行与
\R
;
- 它允许在 "knop." 之前最多放置两个自由字符(您可以使用这 2 个来允许更多或更少);
- 它允许 spaces 在 "knop." 之后出现
\h
(水平白色 space);
- 在 "knop." 和一些可选的空格之后,该行必须结束:
\R
或 $
(结束)
- 替换注意将 "knop." 附加到上一行,并且在它和上一行的最后一个单词之间恰好有一个 space。
请注意,如果您向浏览器发送包含 \n
的 echo
文本,它不会在这些位置显示换行符,而只会显示 space,并生成输出长线。要强制浏览器将 \n
显示为换行符,请将输出包装在 pre
标记中,如下所示:
echo "<pre>$text</pre>";
我不知道您发布的结构本身是否代表您要处理的所有文本,但我看到文本中出现了一种模式。除了检查行中是否只有 "knop."
之外,您当然可以选择尝试恢复换行,方法是连接 "Område" 中的字符串,直到第一次出现句号/句点。这样做的好处是您可以按照自己认为合适的方式处理文本。
<?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));
这会产生以下结果:
string(383) "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"
这似乎回答了您的问题,只是方式不同 ;)
示例文本:
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" 是否在下一行以及下一行是否少于 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 个字符长的行作出反应。
我显然做错了什么,我已经弄清楚了...;-)
您的正则表达式匹配每个 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|$))/', '', $Lines);
print_r(explode("\n", $Result));
正则表达式演示:https://regex101.com/r/oJ3uB0/1
还要注意分解中替换值的用法。
PHP 演示:https://eval.in/510853
将整个文本(多行)放在一个字符串中,然后你可以在上面使用这个正则表达式来清理它:
// 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|$)#', " \n", $text);
// rebuild Lines variable.
$Lines = explode("\n", $text);
preg_replace正则表达式和替换的一些解释:
- 需要前一行与
\R
; - 它允许在 "knop." 之前最多放置两个自由字符(您可以使用这 2 个来允许更多或更少);
- 它允许 spaces 在 "knop." 之后出现
\h
(水平白色 space); - 在 "knop." 和一些可选的空格之后,该行必须结束:
\R
或$
(结束) - 替换注意将 "knop." 附加到上一行,并且在它和上一行的最后一个单词之间恰好有一个 space。
请注意,如果您向浏览器发送包含 \n
的 echo
文本,它不会在这些位置显示换行符,而只会显示 space,并生成输出长线。要强制浏览器将 \n
显示为换行符,请将输出包装在 pre
标记中,如下所示:
echo "<pre>$text</pre>";
我不知道您发布的结构本身是否代表您要处理的所有文本,但我看到文本中出现了一种模式。除了检查行中是否只有 "knop."
之外,您当然可以选择尝试恢复换行,方法是连接 "Område" 中的字符串,直到第一次出现句号/句点。这样做的好处是您可以按照自己认为合适的方式处理文本。
<?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));
这会产生以下结果:
string(383) "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"
这似乎回答了您的问题,只是方式不同 ;)