-->

我有一个PHP的正则表达式,如何添加一个条件的字符数?(I have a PHP regEx, ho

2019-08-04 11:56发布

我有林在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语句来他们淘汰。

Answer 1:

分裂的魔力。 我原来的设想在技术上是不正确的(虽然一个解决方案更容易来)。 因此,让我们检查你的拆分模式:

(\/|\.|-|_|=|\?|\&|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
)


Answer 2:

我猜你建立某种形式的URL路由器。

检测哪些参数是有用的,这是不是不应该是这个代码的一部分。 短参数是否是相关的,可能每页会有所不同。

在这种情况下,能不能别忽略了1首元素? 您的页面应该(或“处理”)应具有的知识在哪些参数,它希望与调用,它应该做的分流。



Answer 3:

我认为,如果你试图获得来自URL意思是,你实际上要编写干净的URL中,这样你就不需要复杂的正则表达式来获得的价值的一种方式。

在许多情况下,这涉及到使用服务器重定向规则和前端控制器或请求路由器。

所以,你建什么是干净的URL的像

/value1/value2/value3

没有任何.html.php等在URL中的。

在我看来,你都没有解决在入境点进入系统的问题(即Web服务器),充分,使您的网址解析,因为它应该是简单。



Answer 4:

如何努力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

希望这可以帮助



Answer 5:

不要使用正则表达式来掰开该路径。 只需使用explode

$dirs = explode( '/', urldecode($path) );

然后,如果你需要掰开阵列的单个元素,做到这一点,喜欢在年底你“的PageRank更新”元素。

编辑:

关键是,你有两个不同的问题。 首先,你要掰开的斜线路径元素。 然后,你要的文件名分解成更小的部分。 不要试图所有东西都塞进试图做的一切一个正则表达式。

三个分立的步骤:

  • $迪尔斯=爆炸...
  • 剔除参数<3个字符
  • 分手文件参数在年底

如果你打破了你的逻辑成离散的逻辑块,而不是试图使正则表达式尽一切已经非常清晰。



文章来源: I have a PHP regEx, how do add a condition for the number of characters?