RegExp Language Routing

Хорошего дня,

Мне нужен 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&param=Value

(Обратите внимание на косую черту в некоторых строках)

Древовидная структура … ну бесконечно 🙂

Есть случаи с одним и несколькими URL-параметрами.

Я абсолютно не волшебник регулярных выражений, я справился с этим результатом в … часах:

/^\/([a-z]{2})(?:(.*[^\?])|^$)((?:[\/\?]).*|^$)/

Пожалуйста, не спрашивайте меня, что я пытался направить туда. Я оооочень новый для регулярных выражений.
заранее спасибо

Изменить для уточнения (я надеюсь):

По сути, это концепция: (Это внутренняя маршрутизация, без перенаправления, если я не упомянул.)
Параметр языка (как стиль каталога) должен быть взят из 1-го URL и присоединен как реальный параметр с именем «lng». Каталог-параметр должен исчезнуть.
Если уже есть другие параметры, их также необходимо присоединить (? /&-дело).
Если язык не указан (= язык по умолчанию), в URL отсутствует параметр каталога style. Было бы неплохо, если бы еще можно было присоединить параметр? 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

Он всегда маршрутизируется с реальным языковым параметром.
Я также отредактировал первый пост, в нем была запутанная опечатка.

1

Решение

Извините за задержку @hcm.
Ну, я должен сказать тебе. Я потратил 10 минут на написание оригинального регулярного выражения.
Протестировано в Perl, все отлично работает.

Затем я отправляю его в онлайн-тестер php и получаю сообщение об ошибке «Предупреждение о неопределенном смещении».
Захватывать группы 2,3,4 необязательно, поэтому я делаю (?: ( capture ) )? но php такой беспорядок
вы can't even test for undefined group.

Обновить
@hcm — Хорошо, разобрался. Эти онлайн-тестеры не переводят CRLF в LF.
Поэтому при использовании многострочного режима $ является границей перед новой строкой или концом строки.
^ после новой строки или начала строки, что не проблема.

Так, $ не будет соответствовать до CR только перед LF. Обходной путь, вероятно, использует
\R любая конструкция разрыва строки, но это не граница, это фактический характер.
Что я сделал, чтобы вылечить это использовать (?: $ | (?= \r) ) вне утверждений и
(?: $ | \r ) внутри утверждения. Это излечивает все проблемы.

После прочтения вашего сообщения я изменил регулярное выражение, чтобы каждая часть была необязательной, но
по-прежнему позиционный.

4 необязательные части заключаются в следующем.
1. Перед кодом языка.
2. Код Ланга.
3. После кода ланга.
4. Параметры.

Ни одна часть не будет перебивать другую.
Все ведущие /‘ы взяты из каждой части (не часть матча),
в то время как внутренние косые черты остаются на месте.

Осталось только создать новый URL, как вы хотите.
Дайте мне знать, как это получается или если вам нужно немного подправить.

Код 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

Regex

 # '~^(?![^\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 )
)
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]