2013-05-23 4 views
1

Я создаю библиотеку маршрутизатора для преобразования просто определенного шаблона в регулярное выражение, которое впоследствии может использоваться для сравнения URL-адреса. Это значит, что правила могут быть определены просто, и библиотека позаботится обо всем остальном.Подходящее регулярное выражение для замены элементов в строке

Допустим, что строка /*/#:id/# передана в библиотеку, я бы хотел получить /^\/(.{1}.*)\/(?<id>[0-9]{1}[0-9]*)\/([0-9]{1}[0-9]*)$/i. Первоначально библиотека была предназначена для обработки только конвертирования * и # в соответствие любому тексту ((.{1}.*)) и соответствует числу (([0-9]{1}[0-9]+)) соответственно, но теперь я хочу включить опцию для указания конкретных совпадений. Выполнение простой замены строки не будет работать.

Первоначально я думал о том, функции разбора через всю строку, когда символы * или # встречается, он будет проверить следующий символ, и если это :, это будет продолжаться до тех пор, не a-z характера , в этот момент он примет эту фразу, заключит ее в пределах ?< и >, затем подходящий шаблон для того, что было ранее найдено, и, наконец, заключить все в скобки, а затем продолжить, но на практике это не наиболее эффективным способом, и когда я пытаюсь определить более 50 правил, время обработки займет приблизительно 50 мс, и если вы считаете, что это все еще часть процесса начальной загрузки, это кажется слишком длинным, особенно когда сложный webapp может иметь более 200 правил URL.

Я посмотрел на функции замены регулярных выражений, но на данный момент это немного перевернуто над моей головой ... Я не уверен, что это будет лучшее решение, если это решение вообще. Итак, кто-нибудь знает, как это может быть достигнуто, или, возможно, есть лучшее решение, которое могло бы выполнить то, что я пытаюсь своевременно?

Дополнительная

Следует также отметить, что некоторые правила, которые я включают в себя может выглядеть следующим образом:

/*:init-test/#/* 

, который будет соответствовать URL, как

/foo-test/123/asdf 
/bar-test/456/jkl 

Еще одно правило, я планирую мощь выглядят так:

/*:init:test/#/* 

, который будет соответствовать URL, как

/footest/123/asdf 
/bartest/456/jkl 
+1

Есть причина, вы используете '. {1}. *' 'Против .. *' или '. +'? Кроме того, как часто вы пытаетесь выполнить это сопоставление, поскольку вы говорите, что пятая часть второго дополнительного времени загрузки является неприемлемой, что, я думаю, будет хорошо для большинства случаев использования. – Guvante

+0

@Guvante Я использую '. {1}.* ', чтобы гарантировать, что он по крайней мере один по длине, поэтому URL-адреса, такие как' // 123/asdf', не будут истинными, но учитывая эти две альтернативы, это делает его более простым, и я должен был бы, позвольте ему пропустить его ... И что касается второго пункта, как правило, мне не нравится, когда сценарий занимает больше 100 мс для запуска, главным образом потому, что если он находится под интенсивной нагрузкой, он будет работать медленно и (в зависимости от пакет хостинга), он может начать бросать 503 – topherg

ответ

1

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

Далее вы захотите заменить свои особые случаи, сначала любые именованные вещи.

\*(:[A-Za-z]+:?)? ---> (?<\2>.+) 
\#(:[A-Za-z]+:?)? ---> (?<\2>\d+) 

И тогда неименованных вещи

\* ----> .+ 
\# ----> \d+ 
Смежные вопросы