美好的一天,
我需要基于网站客户端语言的Route-RegExp。 它应该是这样的:
Relative URL / Route:
/(No-Language) -> /?lng=(someDefaultLanguage)
/(No-Language)/ -> /?lng=(someDefaultLanguage)
/lngCode/page -> /page/?lng=lngCode
/lngCode/page/ -> /page/?lng=lngCode
/lngCode/pageL1/pageL2 -> /pageL1/pageL2/?lng=lngCode
/language/page?param=Value -> /page/?lng=lngCode¶m=Value
(注意某些行上的尾部斜杠)
树结构是......无限的:)
有一些URL-Params的单个和多个。
我绝对没有正则表达式向导,我在uhm中管理了这个结果,......小时:
/^\/([a-z]{2})(?:(.*[^\?])|^$)((?:[\/\?]).*|^$)/
请不要问我在那里尝试的路线。我是正则表达式的新手。 提前谢谢
-
编辑澄清(我希望):
基本上就是这个概念:(如果我没有提及,它是内部路由,没有重定向。) 必须从第一个URL抓取语言参数(作为目录样式)并附加为名为“lng”的真实参数。 directory-parameter应该会消失。 如果已经存在其他参数,则还需要附加它们(?/& -case)。 如果没有给出语言(= default-language),则url中没有directory-style-parameter。如果仍然可以附加?lng = en参数,那就太好了。
示例:
localhost/blogpage/coolentry (default language)
localhost/de/blogpage/coolentry
localhost/es/blogpage/coolentry
localhost/blogpage/ -> localhost/blogpage/?lng=en
localhostde/de/blogpage/ -> localhost/blogpage/?lng=de
localhost/blogpage/coolentry/ -> localhost/blogpage/coolentry/?lng=en
localhost/de/blogpage/coolentry/ -> localhost/blogpage/coolentry/?lng=de
localhost/de/blogpage/coolentry/?entryPage=1 -> localhost/blogpage/coolentry/?lng=de&entryPage=1
它始终使用真实的语言参数进行路由。 我还编辑了第一篇文章,其中有一个令人困惑的错字。
答案 0 :(得分:0)
对不起延迟@hcm 好吧,我得告诉你。我花了10分钟写了原始的正则表达式 在Perl中测试过,一切都很顺利。
然后我将它转储到在线php测试器中,我得到了这个" Undefined offset"错误/警告。
捕获组2,3,4是可选的,所以我做了(?: ( capture ) )?
但是php是如此混乱
你 can't even test for undefined group
。
的更新强>
@hcm - 好的,想通了。这些在线测试人员不会将CRLF翻译成LF
因此,当使用多线模式时,$
在换行符或换行符之前是绑定的
^
位于换行符或字符串的开头之后,这没问题。
因此,$
仅在LF之前的CR之前不匹配。解决方法可能是使用了
\R
任何换行构造,但不是边界,它是一个真实的角色
我所做的就是解决这个问题,就是在断言之外使用(?: $ | (?= \r) )
内部断言(?: $ | \r )
。这可以解决所有问题。
阅读完您的消息后,我已经更改了正则表达式,以便每个部分都是可选的,但是 仍然位置。
4个可选部分如下
1.在郎代码之前。
2.郎代码。
3.郎代码之后。
4.参数。
没有任何部分会跑过另一部分
所有前导/
都从每个部分中取出(不是匹配的一部分),
内部斜线留在原位。
剩下的就是按照自己的意愿构建新网址 让我知道这是怎么回事,或者你是否需要进行一些调整。
PHP代码:
// Go to this website:
// http://writecodeonline.com/php/
// Cut & paste this into the code box, hit run.
$text = '
invalid
/
/de
/de/coolentry
localhost/
localhost/blogpage
localhost/blogpage/
localhost/blogpage/de/
/localhost/blogpage/coolentry/famous invalid
/root/blog/page/cool/entry/?entryPage=1&var1=A&var2=B
localhost/blogpage/coolentry/
localhost/blogpage/de/coolentry/
localhost/blogpage/de/coolentry/
localhost/blogpage/de/coolentry/?entryPage=1
localhost/blogpage/coolentry/?entryPage=2
';
$str = preg_replace_callback('~^(?![^\S\r\n]*(?:\r|$))(?|(?!/[a-z]{2}[^\S\r\n]*(?:/|(?:\r|$)))/?((?:(?!/[a-z]{2}[^\S\r\n]*(?:/|(?:\r|$))|\?|/[^\S\r\n]*(?:\r|$))\S)*)|())(?|/([a-z]{2})(?=/|[^\S\r\n]*(?:\r|$))|())(?|/((?:(?!/[^\S\r\n]*(?:\r|$))[^?\s])+)|())(?|/\?((?:(?!/[^\S\r\n]*(?:\r|$))\S)*)|())/?[^\S\r\n]*(?:$|(?=\r))~m',
function( $matches )
{
///////////////// URL //////////////////
$url = '';
// Before lang code -- Group 1
if ( $matches[1] != '' ) {
$url .= '/' . $matches[1];
}
// After lang code -- Group 3
if ( $matches[3] != '' ) {
$url .= '/' . $matches[3];
}
///////////////// PARAMS //////////////////
$params = '/?lng=';
// Lang code -- Group 2
if ( $matches[2] != '' ) {
$params .= $matches[2];
}
else {
$params .= 'en'; // No lang given, set default
}
// Other params
if ( $matches[4] != '') {
$params .= '&' . $matches[4];
}
///////////////// Check there is a Url //////////////////
if ( $url == '' ) { // No url given, set a default
$url = '/language'; // 'language', 'localhost', etc...
}
///////////////// Put the pieces back together //////////////////
$NewURL = $url . $params;
return $NewURL;
},
$text);
print $str;
输出:
invalid
/language/?lng=en
/language/?lng=de
/coolentry/?lng=de
/localhost/?lng=en
/localhost/blogpage/?lng=en
/localhost/blogpage/?lng=en
/localhost/blogpage/?lng=de
/localhost/blogpage/coolentry/famous invalid
/root/blog/page/cool/entry/?lng=en&entryPage=1&var1=A&var2=B
/localhost/blogpage/coolentry/?lng=en
/localhost/blogpage/coolentry/?lng=de
/localhost/blogpage/coolentry/?lng=de
/localhost/blogpage/coolentry/?lng=de&entryPage=1
/localhost/blogpage/coolentry/?lng=en&entryPage=2
正则表达式
# '~^(?![^\S\r\n]*(?:\r|$))(?|(?!/[a-z]{2}[^\S\r\n]*(?:/|(?:\r|$)))/?((?:(?!/[a-z]{2}[^\S\r\n]*(?:/|(?:\r|$))|\?|/[^\S\r\n]*(?:\r|$))\S)*)|())(?|/([a-z]{2})(?=/|[^\S\r\n]*(?:\r|$))|())(?|/((?:(?!/[^\S\r\n]*(?:\r|$))[^?\s])+)|())(?|/\?((?:(?!/[^\S\r\n]*(?:\r|$))\S)*)|())/?[^\S\r\n]*(?:$|(?=\r))~m'
^ # BOL
(?! # Not a blank line, remove to generate a total default url
[^\S\r\n]*
(?: \r | $ )
)
(?| # BEFORE lang code
(?!
/ [a-z]{2} [^\S\r\n]* # not lang code
(?:
/
| (?: \r | $ )
)
)
/? # strip leading '/'
( # (1 start)
(?:
(?!
/ [a-z]{2} [^\S\r\n]* # not lang code
(?:
/
| (?: \r | $ )
)
|
\? # not parms
|
/ [^\S\r\n]* # not final slash
(?: \r | $ )
)
\S
)*
) # (1 end)
|
( ) # (1)
)
(?| # LANG CODE
/ # strip leading '/'
( [a-z]{2} ) # (2)
(?=
/
| [^\S\r\n]*
(?: \r | $ )
)
|
( ) # (2)
)
(?| # AFTER lang code
/ # strip leading '/'
( # (3 start)
(?:
(?! # not final slash
/ [^\S\r\n]*
(?: \r | $ )
)
[^?\s] # not parms
)+
) # (3 end)
|
( ) # (3)
)
(?| # PARAMETERS
/ \? # strip leading '/?'
( # (4 start)
(?:
(?! # not final slash
/ [^\S\r\n]*
(?: \r | $ )
)
\S
)*
) # (4 end)
|
( ) # (4)
)
/?
[^\S\r\n]* # EOL
(?:
$
| (?= \r )
)