我有一个带有字母和数字的字符串。我只想从字符串中提取字母,包括空格。
我试过这个:
<?php
$competition = 'New York Nationals - 2016';
$year = preg_replace('/[^0-9]/', '', $competition);
$comp = preg_replace('/[^a-zA-Z]/', '', $competition);
echo "[$year, $first, 'Comp Name: $comp Date: $year Rank: $first']";
?>
$comp
的输出NewYorkNationals
但我想要的是New York Nationals
将[^a-zA-Z]
更改为[^a-zA-Zs]
。
<?php
$competition = 'New York Nationals - 2016';
$year = preg_replace('/[^0-9]/', '', $competition);
$comp = preg_replace('/[^a-zA-Zs]/', '', $competition);
echo "[$year, $first, 'Comp Name: $comp Date: $year Rank: $first']";
?>
使用爆炸
$competition = 'New York Nationals - 2016';
$array = explode(' - ', $competition);
$year = $array[1];
$comp = $array[0];
处理连字符周围的可变空间
如@aequalsb评论中所述,您还可以使用preg_split
例如:
$array = preg_split( '/s*?-s*?/', $competition );
即使周围没有(或多个(空格,-
也会将其拆分。
还有另一种方法可以使用数组映射,我喜欢使用它的数组过滤器。 在这种情况下,这有点矫枉过正,但无论如何我都会展示它。
$array = array_filter(array_map('trim', explode('-', $competition)), function($item){ return strlen($item);});
这是做什么的:
数组映射对数组中的所有项目运行一个函数,在本例中trim
删除前导和尾随空格。因此,例如,如果您将示例字符串拆分为-
,您将获得如下所示的内容:
explode('-', $competition);
//output
["New York Nationals "," 2016"]
他们有额外的空间。 数组映射和修剪将删除这些。
现在,数组过滤器将删除数组中回调返回 false 的任何项目。 在这种情况下,正如我提到的,这有点矫枉过正,但一个例子是这个。
explode('-', "New York Nationals -- 2016");
使用 2 个 Hypens,这将输出如下内容:
["New York Nationals ",""," 2016"]
带有一个额外的数组项。 因此,为了删除,我们使用数组过滤器(在数组映射之后(并使用自定义回调(因为我们可能希望将 0 之类的内容保留在那里(
array_filter(["New York Nationals","","2016"], function($item){
return strlen($item);
});
strlen,只是返回字符串的长度,在 PHP 中,0
也是False
所以任何长度为0
的项目都将被删除。
正如我所说,在这种情况下,这是一个矫枉过正的事情,但知道如何做是一件非常有用的事情,所以我把它包括在内只是为了完整。
处理多个连字符
@aequalsb评论中提出了另一个很好的观点:
这里有很多答案...一旦我们得到一些东西,它们都需要改变,这是一个事件
Winston-Salem Time Trials - 2016
对于使用我发布的答案进行此类操作,您可以使用数组弹出来解决此问题,并像这样内爆:
$competition = 'Winston-Salem Time Trials - 2016';
$array = explode('-', $competition);
//$array = ["Winston","Salem Time Trials ", " 2016"]
$year = trim(array_pop($array));
$comp = trim(implode('-', $array));
数组弹出、删除并返回数组中的最后一项。我们可以非常有信心这将是日期。所以它看起来像这样:
$year = trim(array_pop(["Winston","Salem Time Trials ", " 2016"]));
//result
$year = "2016";
$array = ["Winston","Salem Time Trials "];
然后内爆与爆炸相反,爆炸需要$array,将其与分离器(或胶水(重新组合成一根绳子:
$comp = trim(implode('-', ["Winston","Salem Time Trials "]));
//result
$comp = "Winston-Salem Time Trials";
这给我们留下了我们想要的:
$year = "2016";
$comp = "Winston-Salem Time Trials";
我们已经讨论了 Trim 的作用,所以我不会再讨论这个问题。最后一个示例负责连字符周围的变量空格和多个连字符。 在这种情况下,在内爆后修剪它很重要,我们希望保留原始文本空间中的任何空格(可能(。 但是,如果您不希望连字符周围保留任何空格,则可以先使用数组映射和修剪。
这方面的一个例子是:
$competition = 'Winston - Salem Time Trials - 2016'; //note the space "n - S"
$array = array_map('trim', explode('-', $competition));
//$array = array_filter(array_map('trim', explode('-', $competition)));
//array filter would take care of "Winston -- Salem Time Trials", removing the extra hyphen.
//(without array map, trim) $array = ["Winston "," Salem Time Trials ", " 2016"]
//(with array map, trim) $array = ["Winston","Salem Time Trials", "2016"]
$year = array_pop($array); //no need to trim
$comp = implode('-', $array); //no need to trim
//results
$year = "2016";
$comp = "Winston-Salem Time Trials"; //instead of "Winston - Salem Time Trials"
我应该提到这将处理任何数量的连字符。
$competition = 'Winston-Salem-Time-Trials - 2016';
//Output
$year = "2016";
$comp = "Winston-Salem-Time-Trials";
希望这是有道理的。 正如他们所说"上帝和魔鬼在细节中"。 通常,任何编程中最困难的部分是处理所有边缘情况。
如果你想在正则表达式中做同样的事情
preg_match('/(.+?)s*-s*(d+)$/', $str, $match)
在线测试
基本上捕获所有?
非贪婪,然后是空格或更多,连字符,空格没有或更多,然后是数字,最后是行尾锚点。我碰巧也很擅长正则表达式。 我只是不想踩到任何人的脚趾,因为其他答案都集中在它上面。
享受!
试试这个:
<?php
$str = "This is sample string containing number 172, special chars )(*&^%$#@!':;[]{}><?";
preg_match_all('/[a-zA-Zs]+/', $str, $matches);
print_r($matches);
?>
输出:
Array
(
[0] => Array
(
[0] => This is sample string containing number
[1] => special chars
)
)
在线演示:在此处输入链接说明
如果您的原始字符串具有可预测的格式,您还可以使用preg_match
来获取您的部分,而不是替换:
$competition = 'New York Nationals-2016';
// Define two capturing groups, first alphanumeric characters.
// Optional whitespaces and dash separator.
// Second composed of four digits.
// U modifier: Ungreedy match. Try to match as little characters as possible
// so trailing whitespace is not captured.
$expr = '/^([a-zA-Zs]+)s*-?s*([0-9]{4})$/U';
// Check that we got all parts we are interested in
if (preg_match($expr, $competition, $matches)) {
$comp = $matches[1];
$year = $matches[2];
echo "Comp Name: $comp Date: $year";
}