如何提取字符串中跟随特定关键字的子字符串?

时间:2018-07-17 14:12:11

标签: php string substring

我需要处理大多数具有常规格式/结构的字符串。基本上,该字符串包含3个始终以相同顺序出现的关键字:ATLPáscoaATLNatalATLVerão

这些关键字之间是未知数量的空格字符。另外,每个关键字都有可能跟在一个日期值后面,该日期值可能由非空格和空格字符组成。

与他们的关键字相关联,我想声明3个分别称为$datePáscoa$dateNatal$dateVerão的变量,并将日期子字符串分配给这些变量。

这是一个例子:

$string = 'ATLPáscoa            ATLNatal          ATLVerão     Turno11-03a07desetembro';

我想要的输出是:

$datePáscoa = '';
$dateNatal = '';
$dateVerão = 'Turno11-03a07desetembro';

这里是另一个示例:

$string = 'ATLPáscoa  bananas   ATLNatal xyza sd af          ATLVerão      Turno11-03a07desetembro';

我的预期输出是:

$datePáscoa = 'bananas';
$dateNatal = 'xyza sd af';
$dateVerão = 'Turno11-03a07desetembro';

我尝试使用str_replace(),但显然不是这样:

$string = str_replace("Atelier","",$string );
$string = str_replace("Páscoa","",$string );
$string = str_replace("Natal","",$string );
$string = str_replace("Verão","",$string );

如何提取日期值并将这些值分配给适当的变量?

2 个答案:

答案 0 :(得分:1)

代码:(Demo <- with an alternative input string

$string = 'ATLPáscoa  banana   ATLNatal xyza sd af          ATLVerão      Turno11-03a07desetembro';

$datePáscoa = preg_match('~ATLPáscoa\s*\K(?!ATL)\S+(?:\s+(?!ATL)\S+)*~u', $string, $out) ? $out[0] : '';
$dateNatal = preg_match('~ATLNatal\s*\K(?!ATL)\S+(?:\s+(?!ATL)\S+)*~u', $string, $out) ? $out[0] : '';
$dateVerão = preg_match('~ATLVerão\s*\K\S+(?:\s+\S+)*~u', $string, $out) ? $out[0] : '';

echo '$datePáscoa = '; var_export($datePáscoa); echo "\n";
echo '$dateNatal = '; var_export($dateNatal); echo "\n";
echo '$dateVerão = '; var_export($dateVerão);

输出:

$datePáscoa = 'banana'
$dateNatal = 'xyza sd af'
$dateVerão = 'Turno11-03a07desetembro'

如果这是我的项目,我可能会构建一个正则表达式函数调用,该调用返回一个数组中的所有匹配项,然后在需要时提取所需的内容。您已经请求了单独命名的变量,所以我认为3个函数调用将最简单地演示。

您提供的输入不需要包含u模式修饰符,但是如果您的实际数据需要它,我会添加它。

\K告诉正则表达式引擎从全字符串匹配中“释放先前匹配的字符”-这是为了避免使用捕获组,并确保您返回的值只是“白肉”。相同的原因是为什么您看到\S+(?:\s+\S+)* -匹配一个“单词”,然后可选地匹配一个或多个空格,后跟另一个“单词”。

我在演示中使用var_export()来显示结果中没有开头或结尾的空白字符。

前两个模式中的

(?!ATL)用于避免“过度匹配”或基本上“过度匹配”。第三种模式不需要考虑这一点。

答案 1 :(得分:0)

好吧,由于ATL遍及每个部分,所以我将从爆炸开始:

$array = explode("ATL", $string);

请注意,$ array [0]将是一个空字符串(在这种情况下,但正如我所见,每次都会得到相同类型的输入),然后像这样修剪前导和尾随空格:

for ( $i = 0; $i < count($array); $i++ ) {
 trim($array[$i]);
}

然后复制到各自的变量中:

$datePáscoa = $array[1];
$dateNatal = $array[2];
$dateVerão = $array[3];

此时,它们仍然包含其名称,因此我们用strpos()(返回特定字符串的位置)和strstr()(从给定指针返回字符串的一部分)的组合剪切它,例如:

$datePáscoa = strstr($datePáscoa,strpos($datePáscoa," ")+1);

那是一个空白。之后,可能会再次修剪它们,因为它们可能仍在strstr后包含一些空格。