我有林在PHP中使用正则表达式:
$word_array = preg_split(
'/(\/|\.|-|_|=|\?|\&|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|%|\+)/',
urldecode($path), NULL, PREG_SPLIT_NO_EMPTY
);
它的伟大工程。 它采用URL PARAMATERS喜欢的块:
/2009/06/pagerank-update.html
并返回像的数组:
array(4) {
[0]=>
string(4) "2009"
[1]=>
string(2) "06"
[2]=>
string(8) "pagerank"
[3]=>
string(6) "update"
}
我唯一需要的是,它也不会返回少于3个字符的字符串 。 因此, "06"
字符串是垃圾,我目前使用if语句来他们淘汰。
分裂的魔力。 我原来的设想在技术上是不正确的(虽然一个解决方案更容易来)。 因此,让我们检查你的拆分模式:
(\/|\.|-|_|=|\?|\&|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|%|\+)
我重新安排它一下。 外括号是没有必要的,我提出的单字符到末字符类:
html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|[\/._=?&%+-]
对于一些前期排序。 让我们把这种模式分割样式, s
在短期和定义它。
你想匹配的是从分割的模式,以最低的三个字符这些字符不是所有的部件。
我可以用下面的方式实现这一目标,包括支持正确的分序列和Unicode支持。
$pattern = '/
(?(DEFINE)
(?<s> # define subpattern which is the split pattern
html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|
[\\/._=?&%+-] # a little bit optimized with a character class
)
)
(?:(?&s)) # consume the subpattern (URL starts with \/)
\K # capture starts here
(?:(?!(?&s)).){3,} # ensure this is not the skip pattern, take 3 characters minimum
/ux';
或更小:
$path = '/2009/06/pagerank-update.htmltesthtmltest%C3%A4shtml';
$subject = urldecode($path);
$pattern = '/(?(DEFINE)(?<s>html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|[\\/._=?&%+-]))(?:(?&s))\K(?:(?!(?&s)).){3,}/u';
$word_array = preg_match_all($pattern, $subject, $m) ? $m[0] : [];
print_r($word_array);
结果:
Array
(
[0] => 2009
[1] => pagerank
[2] => update
[3] => test
[4] => testä
)
同样的原理也可以搭配preg_split
为好。 这是一个有点不同:
$pattern = '/
(?(DEFINE) # define subpattern which is the split pattern
(?<s>
html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|
[\/._=?&%+-]
)
)
(?:(?!(?&s)).){3,}(*SKIP)(*FAIL) # three or more is okay
|(?:(?!(?&s)).){1,2}(*SKIP)(*ACCEPT) # two or one is none
|(?&s) # split @ split, at least
/ux';
用法:
$word_array = preg_split($pattern, $subject, 0, PREG_SPLIT_NO_EMPTY);
结果:
Array
(
[0] => 2009
[1] => pagerank
[2] => update
[3] => test
[4] => testä
)
这些程序作为工作要求。 但是,这也有其性能与价格。 成本是类似于旧的答案。
相关的问题:
- Antimatch用正则表达式
- 通过分隔符分割字符串,但如果它被转义
旧的回答,做两步处理(第一剖开,然后过滤)
由于您使用的是常规分割,它会分裂 - 无论长短。
所以你可以做的是筛选结果。 您可以使用正则表达式(再次做到这一点preg_filter
),例如,一个被丢弃一切较小的三个大字:
$word_array = preg_filter(
'/^.{3,}$/', '$0',
preg_split(
'/(\/|\.|-|_|=|\?|\&|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org|%|\+)/',
urldecode($path),
NULL,
PREG_SPLIT_NO_EMPTY
)
);
结果:
Array
(
[0] => 2009
[2] => pagerank
[3] => update
)
我猜你建立某种形式的URL路由器。
检测哪些参数是有用的,这是不是不应该是这个代码的一部分。 短参数是否是相关的,可能每页会有所不同。
在这种情况下,能不能别忽略了1首元素? 您的页面应该(或“处理”)应具有的知识在哪些参数,它希望与调用,它应该做的分流。
我认为,如果你试图获得来自URL意思是,你实际上要编写干净的URL中,这样你就不需要复杂的正则表达式来获得的价值的一种方式。
在许多情况下,这涉及到使用服务器重定向规则和前端控制器或请求路由器。
所以,你建什么是干净的URL的像
/value1/value2/value3
没有任何.html
, .php
等在URL中的。
在我看来,你都没有解决在入境点进入系统的问题(即Web服务器),充分,使您的网址解析,因为它应该是简单。
如何努力preg_match()
而不是preg_split()
图案(使用断言 ):
/([a-z0-9]{3,})(?<!htm|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org)/iu
函数调用:
$pattern = '/([a-z0-9]{3,})(?<!htm|html|shtml|www|php|cgi|htm|aspx|asp|index|com|net|org)/iu';
$subject = '/2009/06/pagerank-update.html';
preg_match_all($pattern, $subject, $matches);
print_r($matches);
你可以在这里尝试的功能: functions-online.com/preg_match_all.html
希望这可以帮助
不要使用正则表达式来掰开该路径。 只需使用explode
。
$dirs = explode( '/', urldecode($path) );
然后,如果你需要掰开阵列的单个元素,做到这一点,喜欢在年底你“的PageRank更新”元素。
编辑:
关键是,你有两个不同的问题。 首先,你要掰开的斜线路径元素。 然后,你要的文件名分解成更小的部分。 不要试图所有东西都塞进试图做的一切一个正则表达式。
三个分立的步骤:
- $迪尔斯=爆炸...
- 剔除参数<3个字符
- 分手文件参数在年底
如果你打破了你的逻辑成离散的逻辑块,而不是试图使正则表达式尽一切已经非常清晰。