簡體   English   中英

正則表達式從帶有分隔符的字符串中提取另一個表達式

[英]Regular expression to extract another expression from a string with delimiters

這個問題有點奇怪,我花了一些時間來推動我對正則表達式的了解,以達到它的目的。 然而,我卻陷入了最后一點。 問題如下:

我有一個字符串(表示我正在修改的路由系統中的URL),它可能包含一個匹配某個段的正則表達式。 例如:

$pattern = "/some/path/to/</[a-z]+/>regex_var1/location";

這里要注意的重要事項是:

  • 正則表達式在字符串中用</ />分隔(除非由於遺留原因它的世界末尾,否則這不是特別可選的。我寧願保留原樣)。
  • /> (regex_var1)之后的文本位是此參數匹配的名稱。 我需要將其保留在表達式之外,以使其與系統的其余部分兼容,足以說在此上下文中可以忽略它。
  • 此url模式將匹配/some/path/to/another/location

我想要實現的是將給定格式(如上所示)分割成段。 這些段用於回溯樹遍歷以將請求URI與控制器匹配。 目前不支持正則表達式,我的意圖是允許這樣做。 在過去,每個段都用/表示,但是我需要包含正則表達式中的/字符。 如果我在它的當前形式中使用它,則表達式分為兩個段。 例如

$pattern = "/some/</([a-z]+)(/optional)?/>regex2/location";
$segments = preg_split('/(?<!<)\/(?!>)/', $pattern);

產生4個部分

// print_r($segments)
Array
(
    [0] => 
    [1] => some
    [2] => </([a-z]+)(
    [3] => optional)?/>regex2
    [4] => location
)

當我實際上只想要3

// print_r($segments)
Array
(
    [0] => 
    [1] => some
    [2] => </([a-z]+)(/optional)?/>regex2
    [3] => location
)

我不想將整個URL與正則表達式匹配,這會破壞練習的全部要點。 這個問題可能在單獨的情況下看來是沒有根據的,但有關我在此具體實現后的原因的詳細信息超出了問題的范圍。

嗯,我看不到只用正則表達式做一個簡單的方法。 您可能首先解析正則表達式(/< /<\\/.*?\\/>[^\\/]*/ ),將它們存儲在一個數組中並用簡單但不碰撞的東西替換它們( $1 ),然后運行你的正則表達式並重新插入正則表達式。

另一種方法:

$str = "/some/</([a-z]+)(/optional)?/>regex2/location";
$out_segments = array();
$in_regex = false;
foreach(preg_split('+/+', $str) as $segment) {
    if ($in_regex) {
        if (substr($segment, 0, 1) === '>') {
            $in_regex = false;
        }
        $out_segments[count($out_segments) - 1] .= "/$segment";
        continue;
    }
    if (!$in_regex && substr($segment, -1, 1) === '<') {
        $segment = substr($segment, 0, -1);
        if ($segment !== '') {
            $out_segments[] = $segment;
        }
        $in_regex = true;
        $segment = '<';
    }
    if ($segment !== '') {
        $out_segments[] = $segment;
    }
}
var_dump($out_segments);

編輯:錯誤的偽代碼看起來更容易。 不過,這個想法並不是那么糟糕。

您可以先嘗試將字符串拆分為其組件,然后再處理它:

$url = '/some/location/</([a-z]+)(/optional)?/>regex2/here/or/there';
$reg = '#(.*?)(</.*?/>.*?(?=/|$))(.*)?#';
if( preg_match($reg, $url, $matches) ) {
    $result = array_merge(
        preg_split( '#/#', $matches[1], 0, PREG_SPLIT_NO_EMPTY),
        array( $matches[2] ),
        preg_split( '#/#', $matches[3], 0, PREG_SPLIT_NO_EMPTY)
    );
    print_r( $result );    
}

Array
(
    [0] => some
    [1] => location
    [2] => </([a-z]+)(/optional)?/>regex2
    [3] => here
    [4] => or
    [5] => there
)

正則表達式應始終位於$matches[2] ,因此無論URL出現在何處,您都可以找到它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM