正确的正则表达式从谷歌字体链接src检测字体系列名称

时间:2015-04-22 15:47:52

标签: php regex wordpress

我一直试图获取我在wordpress主题上的一系列字体。这仅用于测试。

输入时:

http://fonts.googleapis.com/css?family=Arimo:400,700|Quicksand:400,700|Cantarell:400,700,400italic,700italic|Muli:300,400,300italic,400italic|Roboto+Slab:400,700|Share:400,700,400italic,700italic|Inconsolata:400,700|Karla:400,700,400italic,700italic|Maven+Pro:400,500,700,900|Roboto+Slab:400,700|Open+Sans:400italic,600italic,700italic,400,600,700

我需要的输出是这样的:

array(
[0] => 'Arimo',
[1] => 'Quicksand',
[2] => 'Cantarell',
... so on
)

直到现在,除了一个小问题,我几乎完成了所有事情。

我的代码:

$input = 'http://fonts.googleapis.com/css?family=Arimo:400,700|Quicksand:400,700|Cantarell:400,700,400italic,700italic|Muli:300,400,300italic,400italic|Roboto+Slab:400,700|Share:400,700,400italic,700italic|Inconsolata:400,700|Karla:400,700,400italic,700italic|Maven+Pro:400,500,700,900|Roboto+Slab:400,700|Open+Sans:400italic,600italic,700italic,400,600,700';

$against = "/[A-Z][a-z]+[\+][A-Z][a-z]+|[A-Z][a-z]+/";

$matches = array()

preg_match_all( $against, $input, $matches );

print_r($matches);

从这里,输出如下:

array(
0   =>  Arimo
1   =>  Quicksand
2   =>  Cantarell
3   =>  Muli
4   =>  Roboto+Slab
5   =>  Share
6   =>  Inconsolata
7   =>  Karla
8   =>  Maven+Pro
9   =>  Roboto+Slab
10  =>  Open+Sans
)

字体名称中包含空格的+符号。我想摆脱它。

我不是正则表达式专家。所以,无法做到这一点。

注意:我知道我可以使用str_replace()执行此操作但不想完成这个漫长的过程。我想知道当我们收集匹配的表达式时,是否有可能逃过+符号并在那里留下空格。

4 个答案:

答案 0 :(得分:0)

在url中编码为加号(+)的空格。你应该解码你的网址。

$input = urldecode($input);

答案 1 :(得分:0)

一般情况下,您需担心的字符数超过+个字段。

必须使用percent-encoding&)对特殊字符(例如&符号(%xx)和URL查询参数中的非ASCII字符进行转义。此外,提交HTML表单时,使用+字符对空格进行编码。

例如:

  • 字体系列" Jacques&吉勒"将被转义为:

    Jacques+%26+Gilles

  • 以UTF-8(U+1E99 (LATIN SMALL LETTER Y WITH RING ABOVE) E1 BA)序列化为八位字节的Unicode字符99将被转义为:

    %e1%ba%99

要执行您想要的正确,您必须从URL中提取查询字符串,并使用parse_str()提取name=value对。 parse_str()函数会自动urldecode()包含+个字符的名称和值。

首先,拆分?字符上的URL以提取查询字符串:

$url = 'http://fonts.googleapis.com/css?family=Arimo:400,700|...|Maven+Pro:400,500,700,900|Roboto+Slab:400,700|...';

$a = explode ('?', $url, 2);
if (isset ($a[1])) {
  $query = $a[1];
}

您也可以使用parse_url ($url, PHP_URL_QUERY),但在这种情况下,它并不会给您带来太多的好处。

然后提取所有参数:

if (isset ($query)) {
  parse_str ($query, $params);

  if (isset ($params['family'])) {
    /* OK: Extract family names. */
  } else {
    /* Error: No family parameter found. */
  }
} else {
  /* Error: No query string found. */
}

注意:您应始终指定parse_str()的第二个参数,以避免破坏现有变量。

答案 2 :(得分:0)

没有正则表达式:

$query = strtr(substr(parse_url($url, PHP_URL_QUERY),7), '+', ' ');

$result = array_map(function ($i) { return explode(':', $i)[0]; }, explode('|', $query));

使用正则表达式:

if (preg_match_all('~(?:\G(?!\A)|[^?&]+[?&]family=)([^:|&]+):[^:|&]*(?:[|&#]|\z)~', strtr($url, '+', ' '), $m))
   $result2 = $m[1];

答案 3 :(得分:0)

从你的代码中,输出给我这样的东西。

array([0] => array([0]   =>  Arimo[1]   =>  Quicksand[2]   =>  Cantarell[3]   =>  Muli[4]   =>  Roboto+Slab[5]   =>  Share[6]   =>  Inconsolata[7]   =>  Karla[8]   =>  Maven+Pro[9]   =>  Roboto+Slab[10]  =>  Open+Sans))

如果是正确的,那我就解决了这个问题'+'。这是解决方案。

$input = 'http://fonts.googleapis.com/css?family=Arimo:400,700|Quicksand:400,700|Cantarell:400,700,400italic,700italic|Muli:300,400,300italic,400italic|Roboto+Slab:400,700|Share:400,700,400italic,700italic|Inconsolata:400,700|Karla:400,700,400italic,700italic|Maven+Pro:400,500,700,900|Roboto+Slab:400,700|Open+Sans:400italic,600italic,700italic,400,600,700';

$against = "/[A-Z][a-z]+[\+][A-Z][a-z]+|[A-Z][a-z]+/";

$matches = array();
$newArr=array();
preg_match_all( $against, $input, $matches );

for($i=0;$i< count($matches);$i++){
    for($j=0;$j< count($matches[$i]);$j++){
        $string=preg_replace('/[^A-Za-z0-9\-]/', ' ', $matches[$j]);
        if($string!=""){
            $newArr[]=$string;
        }
    }    
}
print_r($newArr);