我有一个包含字母和数字的字符串。我只想从字符串INCLUDING空格中提取字母。
我尝试过:
<?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
答案 0 :(得分:1)
将[^a-zA-Z]
更改为[^a-zA-Z\s]
。
<?php
$competition = 'New York Nationals - 2016';
$year = preg_replace('/[^0-9]/', '', $competition);
$comp = preg_replace('/[^a-zA-Z\s]/', '', $competition);
echo "[$year, $first, 'Comp Name: $comp Date: $year Rank: $first']";
?>
答案 1 :(得分:1)
使用爆炸
$competition = 'New York Nationals - 2016';
$array = explode(' - ', $competition);
$year = $array[1];
$comp = $array[0];
处理连字符周围可变的空间
如@aequalsb的评论中所述,您也可以使用preg_split
例如:
$array = preg_split( '/\s*?-\s*?/', $competition );
哪怕-
周围没有(或多于一个)空格,也会将其拆分。
还有另一种使用数组映射的方法,我喜欢使用数组过滤器。在这种情况下,这有点矫kill过正,但我还是会展示它。
$array = array_filter(array_map('trim', explode('-', $competition)), function($item){ return strlen($item);});
这是什么:
Array Map对数组中的所有项目运行一个函数,在这种情况下,trim
会删除前导和尾随空白。因此,例如,如果仅将示例字符串分割成-
,就会得到类似这样的内容:
explode('-', $competition);
//output
["New York Nationals "," 2016"]
在有多余空间的地方。 Array Map和Trim将删除那些。
现在数组过滤器将删除回调为其返回false的数组中的所有项目。正如我所提到的,在这种情况下,这有点矫kill过正,但这就是一个例子。
explode('-', "New York Nationals -- 2016");
使用2个连字符,将输出如下内容:
["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 "];
然后爆裂是explode的反义词,它使用$ 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)
基本上捕获?
个非贪婪的所有内容,然后是一个或多个空格,连字符,一个或多个空格,然后是数字,最后是行尾。我恰好也是Regex的佼佼者。我只是不想踩任何人的脚趾,而其他答案都集中在它上面。
享受!
答案 2 :(得分:0)
尝试一下:
<?php
$str = "This is sample string containing number 172, special chars )(*&^%$#@!':;[]{}><?";
preg_match_all('/[a-zA-Z\s]+/', $str, $matches);
print_r($matches);
?>
输出:
Array
(
[0] => Array
(
[0] => This is sample string containing number
[1] => special chars
)
)
答案 3 :(得分:0)
如果您的原始字符串具有可预测的格式,则也可以使用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-Z\s]+)\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";
}