Статьи

Использование регулярных выражений в C # против PHP

Недавно на работе я обратился ко всем инженерам с просьбой прислать мне код, который, по их мнению, должен быть помещен в общую библиотеку для разработки .Net. В одном из ответов я получил электронное письмо от разработчика PHP с регулярным выражением для проверки формата денег. Он заявил, что не знает, как часто мы используем их (ссылаясь на регулярные выражения) в C #, но он думал, что все равно передаст его. Это заставило меня задуматься. Использую ли я регулярные выражения в C # столько же, сколько в PHPU?

Для любопытных, регулярное выражение, которое было отправлено поверх, прекрасно работает в C #, никаких проблем. Я думаю, что разработчики найдут регулярные выражения, легко перейдут от одного к другому. Если вы портируете регулярные выражения PHP на C # и наоборот, вы не должны сталкиваться с большим количеством проблем. Например, вот быстрый тест, который я бросил вместе с регулярным выражением, чтобы убедиться, что он работает.

using System;
using System.Text.RegularExpressions;

class Money
{
public static void Main()
{
Regex exp = new Regex(@"^[1-9][0-9]{0,2}(,{0,1}[0-9]{3})*(\.[0-9]{0,2})$");
Console.WriteLine(exp.IsMatch("123.23").ToString());
}
}

Когда выполнил и выполнил, это дало следующий результат:

Это сработало. Когда дело доходит до регулярных выражений в C #, я использовал их. Я нахожу, что они больше похожи на перец, посыпанный хорошим рагу, а не на основное блюдо. Вот как я бы сказал о разнице в их использовании между двумя языками. Если бы мне пришлось указывать процент от того, насколько меньше я использую регулярных выражений, я бы определенно сказал, что это вдвое меньше, и, возможно, увеличится до 90% в зависимости от ситуации. Почему?

Я думаю, что это сводится к тому, что C # строго типизирован, а PHP — слабо типизирован. Например, следующий код никогда не может быть написан на C #.

<?php
$x = 1;
$y = '2keith';

echo $x + $y; // will print 3 (yes you can add strings and numbers in php)

// set $x to something completely different
$x = array('a', 'b', 'c', 'd');

echo $x[1]; // will print b

?>


Запуск всей вещи приведет к:
3b

Для некоторых этот пример может быть страшным, другие могут рассматривать его как особенность. Как бы вы ни думали, большинство разработчиков, когда их спрашивают, что даст результат, отвечают на все вопросы. Когда я преподавал PHP-классы в качестве консультанта, я использовал аналогичный пример с классом. Ни для кого не исключение, никто не мог предсказать исход. Ответы даны в диапазоне от, это должно вызвать исключение, так как вы не можете добавить строку и число. Или это должно вызвать исключение, потому что переменная $ x была переназначена другому типу.

Понимаете ли вы, почему код PHP больше полагается на регулярные выражения? Поскольку $ x может буквально стать любым типом в любое время, разработчик PHP никогда не может полагаться на тот факт, что $ x является INT. Единственный способ проверить это значение — использовать регулярное выражение. В мире PHP это называется Type Juggling . И наоборот, в C # после того, как переменной x присвоен тип, ее нельзя изменить, и этому типу могут быть назначены только действительные числа, что исключает необходимость использования регулярного выражения для проверки значения переменной.

Тогда возникает вопрос: это C # способ проверить ценность денег? Вероятно, я бы сказал, что это не самый лучший способ обработки денег в C #. Хотя это, безусловно, работает, есть и другие вещи, которые необходимо учитывать при добавлении денег. Например, два разных типа денег, таких как доллары США и евро, не могут быть добавлены вместе. Сначала его нужно обменять, а потом добавить. То же самое можно сказать и о других операторах, выполняемых с переменной типа money. Именно здесь было бы целесообразно использовать структуру и создать новый тип с именем Money.

Мы можем в C # объявить переменную как тип десятичной дроби и использовать ее как деньги, если захотим. В этом случае нам все еще не нужно регулярное выражение для проверки значения нашей переменной. Вот пример, показывающий один способ обработки мошеннического значения:

decimal money;
if (Decimal.TryParse("123.a234", out money))
{
Console.WriteLine("money is valid");
}
else
{
Console.WriteLine("money is invalid");
}

Я подозреваю, что многие программисты используют этот метод, но опять же структура более желательна. У Андре де Кавеньяка есть отличный пример построения структуры для типа денег. Он приводит следующие примеры:

Money eur10 = new Money(MoneyCurrency.Euro, 10);
Money eurNeg10 = new Money(MoneyCurrency.USDollar, -10);
Money usd10 = new Money(MoneyCurrency.USDollar, 10);
Money usdZero = new Money(MoneyCurrency.USDollar, 0);

bool result = (eur10 == usd10); // returns false;
bool result = (eur10 > usd10); // throws InvalidOperationException (comparison not valid)
bool result = (eur10 > Money.Zero); // returns true
bool result = (eur10 > usd0); // returns true
bool result = (usd10 > eurNeg10); // returns true (positive always greater than negative)

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

Для тех, кто интересуется различиями в регулярных выражениях в PHP и C #, я надеюсь, что это даст вам некоторое представление о том, как разные языки соответственно справляются с различными ситуациями. Все сводится к строгой типизации против свободной типизации и способности создавать новые типы на основе структур.