Regex - Если содержит '%', может только содержать '%20'

Пользователь AJAXToolkit от http://asp.net

5
задан Kyle Rozendo 2 December 2009 в 16:50
поделиться

9 ответов

Не требует%:

/^[^%]*(%20[^%]*)*$/
5
ответ дан 13 December 2019 в 22:09
поделиться

Какой язык вы используете?

Большинство языков имеют функцию или класс Uri Encoder / Decoder. Я бы посоветовал вам сначала декодировать строку, а затем проверять действительные (или недопустимые) символы.

т.е. что-то вроде / [\ w] / (пусто - пробел)

С регулярным выражением в первую очередь вам нужно учтите, что www.example.com/index.html?user=admin&pass=%%250 означает, что проход действительно составляет "% 250".

2
ответ дан 13 December 2019 в 22:09
поделиться

Отличная головоломка!

Я вижу, что большинство людей запоминают положение каждой части. Как насчет того, чтобы применить более простой подход и сохранить содержимое каждого квадрата ? Это обеспечивает автоматическое продвижение и захваченные фрагменты.

И это позволяет кодирование Хаффмана . Фактически, начальная частота фигур на доске почти идеальна для этого: половина квадратов пусты, половина оставшихся квадратов - пешки и т. Д.

Учитывая частоту каждой фигуры, я построил Хаффмана дерево на бумаге, которое я здесь повторять не буду. Результат, где c обозначает цвет (белый = 0, черный = 1):

  • 0 для пустых полей
  • 1c0 для пешки
  • 1c100 для ладьи
  • 1c101 для коня
  • 1c110 для слона
  • 1c1110 для ферзя
  • 1c1111 для короля

для всей доски в исходной ситуации у нас есть

  • пустых квадратов: 32 * 1 бит = 32 бита
  • пешек: 16 * 3 бита = 48 бит
  • ладьи / кони / слоны: 12 * 5 бит = 60 бит
  • ферзей / королей: 4 * 6 бит = 24 бита

Всего: 164 бита для начального состояния платы. Значительно меньше, чем 235 бит ответа, получившего наибольшее количество голосов. И он будет только уменьшаться по мере продвижения игры (кроме случаев повышения).

Я смотрел только на положение фигур на доске; дополнительное состояние (чей ход, кто рокировался, на проходе, повторяющиеся ходы и т.д.) нужно будет кодировать отдельно. Может быть, еще 16 бит самое большее, Возможные оптимизации:

  • Исключение менее часто используемых частей и сохранение их позиции отдельно. Но это не поможет ... замена короля и ферзя пустым квадратом позволяет сэкономить 5 бит, а это именно те 5 бит, которые вам нужны для кодирования их позиции другим способом.
  • «Нет пешек на заднем ряду» легко может быть кодироваться с использованием другой таблицы Хаффмана для задних строк, но я сомневаюсь, что это сильно помогает. Вы, вероятно, все равно получите то же дерево Хаффмана.
  • «Один белый, один черный слон» можно закодировать, введя дополнительные символы, у которых нет бита c , которые затем могут быть выводится из квадрата, на котором находится слон. (Пешки, повышенные до слонов, нарушают эту схему ...)
  • Повторение пустых квадратов может быть закодировано по длине серии, введя дополнительные символы, скажем, для "

    ^([^%]|%([013-9a-fA-F][0-9a-fA-F]|2[1-9a-fA-F]))*$
    
1
ответ дан 13 December 2019 в 22:09
поделиться

Отклонить строку, если она соответствует % [^ 2] [^ 0]

1
ответ дан 13 December 2019 в 22:09
поделиться

Я думаю, вы найдете то, что вам нужно

/^([^%]|%%|%20)+$/

Edit : добавлен случай, когда %% является допустимой строкой внутри URI
Edit2 : и исправлен для случая, когда он должен завершиться неудачно: -)
Edit3 :

Если вам нужно использовать его в редакторе (что объясняет, почему вы не можете использовать более программный способ), тогда вам нужно правильно экранировать все специальные символы, например в Vim это регулярное выражение должно быть lool:

/^\([^%]\|%%\|%20\)\+$/
1
ответ дан 13 December 2019 в 22:09
поделиться

Возможно, лучший подход - выполнить эту проверку после того, как вы декодируете эту строку:

string name = HttpUtility.UrlDecode(Request.QueryString["Name"]);
0
ответ дан 13 December 2019 в 22:09
поделиться
/^([^%]|%20)*$/
0
ответ дан 13 December 2019 в 22:09
поделиться

Это требует проверки на "плохие" шаблоны. Если мы разрешаем % 20 - нам не нужно проверять его существование.

Как уже говорили другие, %% тоже действителен ... и %% 25 будет % 25

Приведенное ниже регулярное выражение соответствует всему, что не вписывается в приведенные выше правила

/(?<![^%]%)%(?!(20|%))/

Первые скобки проверяют, стоит ли перед символом% (что означает, что это %% ), а также проверяет, что это не %%% . Затем он проверяет наличие% и проверяет, не соответствует ли элемент после 20

Это означает, что если что-то определено регулярным выражением, вам, вероятно, следует отклонить его.

0
ответ дан 13 December 2019 в 22:09
поделиться

Я согласен с комментарием Доминика по вопросу. Не используйте Regex.

Если вы хотите избежать сканирования строки дважды, вы можете просто итеративно искать % , а затем проверить, что за ним следует 20 и ничего еще. ( Обновление: разрешить % после интерпретировать как буквальную последовательность % nnn )

// pseudo code
pos = 0
while (pos = mystring.find(pos, '%'))
{
     if mystring[pos+1] = "%" then
         pos = pos + 2 // ok, this is a literal, skip ahead
     else if mystring.substring(pos,2) != "20" 
          return false; // string is invalid
     end if
}
return true;
0
ответ дан 13 December 2019 в 22:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: