Laravel - 正则表达式路由匹配所有内容,但不完全匹配一个或多个单词

     2023-03-14     262

关键词:

【中文标题】Laravel - 正则表达式路由匹配所有内容,但不完全匹配一个或多个单词【英文标题】:Laravel - regex route match everything but not exactly one or more word 【发布时间】:2020-04-20 07:50:46 【问题描述】:

我做了一个类似的路线

Route::get('/url1', function ($url1) 
    return ' url1: '.$url1;
)
->where('url1', '^(?!(string1|string2)$)');

并访问如下网址: - domain/abc 未找到 => 不正确 ?? - domain/string1 未找到 => 正确

还有更多,当我这样做时

Route::get('/url1/url2', function ($url1) 
    return ' url1: '.$url1;
)
->where('url1', '^(?!(string1|string2)$)');

并访问网址,例如: - domain/abc/abc 未找到 => 不正确 ??? - domain/string1/abc 未找到 => 正确

如何解决这个问题,谢谢

【问题讨论】:

字符串是静态的还是动态的? @MiteshRathod string1 和 string2 是特殊词(它是静态的) 只有这 2 个字符串在 url 中不接受,对吗? @MiteshRathod 是的,url 中不接受 string1 或 string2 请添加您的正则表达式。 【参考方案1】:

请试试这个 对于第一种情况:

Route::get('/url1', function ($url1) 
    return ' url1: '.$url1;
)->where('url1', '^!(string1|string2)$');

对于第二种情况:

Route::get('/url1/url2', function ($url1, $url2) 
    return ' url1: '.$url1 . ' url2: '.$url2;
)->where('url1', '^!(string1|string2)$');

希望对你有帮助:)

【讨论】:

thankiu 但是,我只是尝试使用domain/abc 进行第一次尝试,但没有找到?【参考方案2】:

试试这个

 Route::get('url1', function ($url1) 
    return ' url1: '.$url1;
)->where('url1','^(?!string1$|string2$)([a-zA-Z0-9-]+)');

实现这一目标的不干净方法

Route::get('url1/url2?', function ($url1,$url2 = null) 
        if ($url2 == "string1" || $url2 == "string2" || $url1 == "string1" || $url1 == "string2") 
            return "false";
         else 
            return "true";
        
);

我尝试过的另一种方法是使用RouteServiceProvider.php

像这样更改您的boot()

public function boot()
    
        //
        Route::pattern('url1', '^(?!string1$|string2$)([a-zA-Z0-9-]+)');
        Route::pattern('url2', '^(?!string1$|string2$)([a-zA-Z0-9-]+)');
        parent::boot();
    

【讨论】:

谢谢,但效果不佳。我只是尝试domain/string1 => 它仍然找到 @DeLe 奇怪我尝试过相同的代码,但它s excluding 127.0.0.1:8000/domain/string2, 127.0.0.1:8000/domain/string1` 并为http://127.0.0.1:8000/domain/abc工作 对不起domain, domain 喜欢http://127.0.0.1:8000,你应该试试127.0.0.1:8000/string1, ... @DeLe 已更新,立即查看。 @DeLe 使用RouteServiceProvider查看更新的答案。【参考方案3】:

经过测试,我认为不可能完全实现您想要的。似乎当您想要排除 string1string2 时,您需要同意以 string1string2 开头的字符串也将被排除(例如 string1aaa)。

使用此类路线时:

Route::get('/url1', function ($url1) 
    return ' url1: '.$url1;
)->where('url1', '(?!string1|string2)[^\/]+');


Route::get('/url1/url2', function ($url1, $url2) 
    return ' url1: '.$url1. ' # '.$url2;
)->where('url1', '(?!string1|string2)[^\/]+');

结果将是:

domain/abc - found, correct
domain/string1 - not found, correct
domain/abc/abc - found, correct
domain/string1/abc - not found, correct
domain/string1aaa - not found, I believe you need to accept this
domain/string1aaa/abc - not found, I believe you need to accept this

我相信这种限制来自 Laravel 而不是来自正则表达式。如果您还需要接受以string1string2 开头的参数,我相信您需要像这样以手动方式进行:

Route::get('/url1', function ($url1) 
    if (!preg_match('#^(?!string1$|string2$)[^\/]*$#', $url1)) 
        abort(404);
    

    return ' url1: '.$url1;
);


Route::get('/url1/url2', function ($url1, $url2) 
    if (!preg_match('#^(?!string1$|string2$)[^\/]*$#', $url1)) 
        abort(404);
    

    return ' url1: '.$url1. ' # '.$url2;
);

【讨论】:

【参考方案4】:

试试这个正则表达式:

    Route::get('/url1', function ($url1) 
        return 'url: '.url1;
    )->where('url1', '^(?!(string1|string2)$)(\S+)');

【讨论】:

thankiu,但是当我尝试http://domain/string1/abc 时它仍然找到?【参考方案5】:

我发现写两条路线更清晰,而不是写一条路线来匹配任何除了某些静态字符串:一条路线匹配某些静态字符串,另一条路线匹配其他所有内容。

// route that matches forbidden static strings, optionally with a postfix slug
$router->get('/forbidden/optional_path?', function () 
    return response('Not found', 404);
)->where([ 'forbidden' => '(?:string1|string2)', 'optional_path' => '.*' ]);

// route that matches anything else (order of definition matters, must be last)
// might also consider using Route::fallback(), but I prefer to leave that
// alone in case my future self changes this below and opens up a hole
$router->get('/anything?', function () 
    return response('Found', 200);
)->where([ 'anything' => '.*' ]);

这会导致*

domain => 找到 200 个 domain/ => 找到 200 个 domain/abc => 找到 200 个 domain/string1 => 404 未找到 domain/string1/ => 404 未找到 domain/string1/abc => 404 未找到 domain/string10 => 找到 200 个 domain/string10/ => 找到 200 个 domain/string10/abc => 找到 200 个 domain/string2 => 404 未找到 domain/string2/ => 404 未找到 domain/string2/abc => 404 未找到 domain/string20 => 找到 200 个 domain/string20/ => 找到 200 个 domain/string20/abc => 找到 200 个

我觉得这更清楚,因为我不必考虑排除项。相反,我可以考虑完全匹配我想要禁止的内容,然后让 Laravel 对其他所有内容做出反应(失败开放策略)。这可能不符合您的设计标准,但我相信它会产生更清晰的代码。

此外,代码的性能更高。 ?! 必须回溯,这在定义上比前向匹配更昂贵。

我手头没有 Laravel 环境,但我会冒险猜测您的尝试为什么没有奏效。 Laravel 使用 does not support lookarounds on slugs 的 Symfony 路由器。 IIRC,当检测到环视时,Symfony 将环视应用到整个 URL,而不是您将模式绑定到的 slug。这与开发人员对锚 (^, $) 和贪婪 (*) 元字符如何工作的想法相混淆。这可能会导致在尝试使其工作时体验不佳,因为开发人员在一个假设下运行,但底层库在另一个假设下运行。


* 完全公开,我是为 Lumen 写的,然后在心里把它转换成 Laravel 格式。可能存在一些翻译错误。这是原始流明:

$router->get('/forbidden:(?:string1|string2)[/optional_path:.*]', function () 
    return response('Not found', 404);
);
$router->get('anything:.*', function ()                                    
    return response('Found', 200);
);

【讨论】:

正则表达式,匹配除 \r \n 之外的所有内容作为普通字符

】正则表达式,匹配除\\\\r\\\\n之外的所有内容作为普通字符【英文标题】:Regex,matcheverythingexcept\\r\\nasnormalcharacter正则表达式,匹配除\\r\\n之外的所有内容作为普通字符【发布时间】:2021-08-2106:12:24【问题描述】:我在C#中使用... 查看详情

匹配正则表达式中的相似字符串,但不是所有出现 [关闭]

】匹配正则表达式中的相似字符串,但不是所有出现[关闭]【英文标题】:Matchsimilarstringinregex,butnotalloccurences[closed]【发布时间】:2022-01-1201:15:08【问题描述】:我想知道是否可以匹配两条或多条相似行中的一条。要匹配的字符... 查看详情

正则表达式:匹配除特定模式之外的所有内容

】正则表达式:匹配除特定模式之外的所有内容【英文标题】:Regex:matcheverythingbutspecificpattern【发布时间】:2010-12-1320:14:30【问题描述】:我需要一个能够匹配所有内容的正则表达式但是一个以特定模式开头的字符串(特别是ind... 查看详情

正则表达式:匹配除一个单词之外的所有内容[重复]

】正则表达式:匹配除一个单词之外的所有内容[重复]【英文标题】:Regex:Matcheverythingbutoneword[duplicate]【发布时间】:2014-12-3001:24:06【问题描述】:我正在寻找一种正则表达式模式,它可以匹配除一个精确单词之外的所有内容。... 查看详情

如何使用正则表达式选择除捕获组之外的所有内容?

】如何使用正则表达式选择除捕获组之外的所有内容?【英文标题】:HowdoIselecteverythingexceptthecapturegroupwithRegex?【发布时间】:2014-11-0102:03:28【问题描述】:问题:暂时忘记下面的一切,因为我的细节似乎让人们感到困惑(否则... 查看详情

必须包含字符串中所有字符的正则表达式匹配

】必须包含字符串中所有字符的正则表达式匹配【英文标题】:Regexmatchthatmustcontainallcharactersinastring【发布时间】:2011-05-0200:25:27【问题描述】:我确定这已经被问及回答了,但老实说,在搜索了相当多的内容并阅读了RegexTutorial... 查看详情

正则表达式 - 如何匹配除特定模式之外的所有内容

】正则表达式-如何匹配除特定模式之外的所有内容【英文标题】:Regex-howtomatcheverythingexceptaparticularpattern【发布时间】:2010-10-1108:16:51【问题描述】:如何编写一个正则表达式来匹配任何不符合特定模式的字符串?我遇到了必须... 查看详情

正则表达式匹配注释(单行或多行)并匹配其他所有内容(C#)

】正则表达式匹配注释(单行或多行)并匹配其他所有内容(C#)【英文标题】:Regexmatchcomments(single-lineormultiple-line)andmatcheverythingelse(C#)【发布时间】:2020-03-2408:53:49【问题描述】:我正在使用C#,我想匹配单行cmets或多行cmets或e... 查看详情

仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配

】仅当字符串包含指定的内容但没有其他内容时,正则表达式匹配【英文标题】:Regexmatchonlyifstringcontainswhatisspecifiedbutnothingelse【发布时间】:2022-01-0901:15:41【问题描述】:我正在尝试在perl中实现一个REGEX,如果字符串包含我指... 查看详情

正则表达式 - 匹配 BEGIN 和 END 之间的所有内容

】正则表达式-匹配BEGIN和END之间的所有内容【英文标题】:RegularExpression-MatchallbetweenBEGINandEND【发布时间】:2018-08-2408:29:48【问题描述】:我正在尝试找出如何创建一个正则表达式来匹配过程块的第一个“BEGIN”和最后一个“END... 查看详情

正则表达式:匹配文本段落中除特定短语外的所有内容

】正则表达式:匹配文本段落中除特定短语外的所有内容【英文标题】:Regex:Matcheverythingintextparagraphexceptspecificphrases【发布时间】:2018-07-0512:19:55【问题描述】:我正在为GoogleDocs编写一个免费插件并处理文本段落。我需要一个... 查看详情

javascript正则表达式匹配两个字符串之间的所有内容(没有换行符)[重复]

】javascript正则表达式匹配两个字符串之间的所有内容(没有换行符)[重复]【英文标题】:javascriptregextomatcheverythingbetweentwostrings(withoutnewline)[duplicate]【发布时间】:2021-05-1217:25:00【问题描述】:我正在尝试匹配两个标签之间的... 查看详情

R中的正则表达式:匹配所有内容,但不匹配“某些字符串”[重复]

】R中的正则表达式:匹配所有内容,但不匹配“某些字符串”[重复]【英文标题】:RegexinR:matcheverythingbutnot"somestring"[duplicate]【发布时间】:2013-07-0111:06:44【问题描述】:另一个问题的答案解释howtomatchastringnotcontainingaword... 查看详情

试图找到所有正则表达式匹配的索引,但有些被遗漏了

】试图找到所有正则表达式匹配的索引,但有些被遗漏了【英文标题】:Tryingtofindindicesofallregexmatches,butsomebeingleftout【发布时间】:2021-05-1710:00:58【问题描述】:我想找到字符串中第一个“e”之后每个元音的索引。由于您无法直... 查看详情

正则表达式替换以匹配包括尖括号在内的所有内容[重复]

】正则表达式替换以匹配包括尖括号在内的所有内容[重复]【英文标题】:regexreplacetomatcheverythingincludingtheanglebrackets[duplicate]【发布时间】:2016-10-0608:04:12【问题描述】:我的输入是如下字符串-somerandomtext<http…anycharacters>more... 查看详情

匹配两个字符串之外的所有内容

...e*anotherstuffhere我想匹配两个星号(*)之外的所有内容。正则表达式后的预期输出:anotherstuffhere我想出了如何匹配(*)/(?&lt;=\\*)(.*)(?=\\*)/内部的所有内容,但 查看详情

常用正则表达式

初识正则表达式^:匹配开头$:匹配结尾[]:范围匹配[a-z]:匹配有小写字母[A-Z]:匹配所有大写字母[0-9]:匹配所有数字.:匹配单个字符*:表示*前面的内容出现0次或多次+:表示+前面的内容出现1次或多次?:表示?前面的内容出现0次或... 查看详情

java正则表达式如何获取字符串中所有匹配内容

参考技术Ajava正则表达式如何获取字符串中所有匹配内容java正则表达式提取需要用到Matcher类。正则规则就是“一个数字加上大于等于0个非数字再加上结束符”Patternpattern=Pattern.pile("(\\\\d)[^\\\\d]*$")Matchermatcher=pattern.matcher(s)if(matcher... 查看详情