none
Регулярные выражения IsMatch RRS feed

  • Вопрос

  • Необходимо построить регулярное выражение, которое позволит узнать о присутствии переменной в формуле.

    Например, у нас есть формула 2+C*X*50. И нужно узнать, содержит ли она переменную X. Вот такое регулярное выражение справляется с этой задачей:

    Regex.IsMatch("2+C*X*50", @"\W(X)\W")

    Однако, если мы немного изменим формулу X*C*50+2 или 2+50*C*X, то предыдущее выражение вернет False.

    У меня есть альтернативное решение - предварительное получение списка всех переменных:

    var matches = Regex.Matches(formula, @"[a-zA-Z](\w+)*");

    но думаю существует более элегантное решение. Надеюсь вы поможете.


    • Изменено LIKORIS 24 июля 2012 г. 8:08
    24 июля 2012 г. 8:01

Ответы

Все ответы

  • У Вас почти то, что нужно. Но несовпадение из-за того что в шаблоне Вы жёстко задаёте знаки присутствия арифметических опереаций, но в конце или начале их не может быть. Вот исправленный шаблон.

    namespace RegExp
    {
      class Program
      {
        static void Main(string[] args)
        {
          string pattern = @"\W?(X)\W?";
          string test = "X*C*50+2";
          Regex rx = new Regex(pattern);
          if (rx.IsMatch(test))
            Console.WriteLine("Совпало");
          else
            Console.WriteLine("Не совпало");
        }
      }
    }

    24 июля 2012 г. 8:13
    Модератор
  • Да работает, но есть один момент, моя вина, сразу не сказал. Переменные могут состоят из нескольких символов (как букв так и цифр - но не вначале).

    К примеру, формула может быть такой:

    X*C*50+2+X2*Xt

    переменные X, X2 и Xt разные.

    24 июля 2012 г. 8:21
  • Значит будет примерно так:

    namespace RegExp
    {
      class Program
      {
        static void Main(string[] args)
        {
          string pattern = @"\W?(X[A-Za-z0-9]?)\W?";
          string test = "X*C*50+2+X2*Xt";
          Regex rx = new Regex(pattern);
          if (rx.IsMatch(test))
            Console.WriteLine("Совпало");
          else
            Console.WriteLine("Не совпало");
        }
      }
    }

    24 июля 2012 г. 8:25
    Модератор
  • Если убрать X:

    C*50+2+X2*Xt

    то выдает "совпало", хотя такой переменной там нет.

    24 июля 2012 г. 8:33
  • Ну да, так и есть. Это шаблон для всех переменных вида X***. Если нужно только для X, нужен предыдущий если для последнего, то этот.
    24 июля 2012 г. 8:36
    Модератор
  • Тогда получается, что одним регулярным выражением тут не обойтись.

    @"\W(X)\W" - для поиска в "середине" формулы
    @"^(X)\W" - вначале
    @"\W(X)$" - вконце

    Оказывается все это можно объединить:

    @"^(X)\W|\W(X)\W|\W(X)$"

    и тогда все работает как надо.

    Yatajga, спасибо!



    • Изменено LIKORIS 24 июля 2012 г. 9:04
    24 июля 2012 г. 8:57
  • Тогда получается, что одним регулярным выражением тут не обойтись.

    @"\W(X)\W" - для поиска в "середине" формулы
    @"^(X)\W" - вначале
    @"\W(X)$" - вконце

    В этом случае можно одним, как предложил высше(pattern = @"\W?(X)\W?"). А когда у вас составные переменные, как Вы сказали X2, Xt, тогда уже нужен второй шаблон.

    string pattern = @"\W?(X[A-Za-z0-9]?)\W?";

    24 июля 2012 г. 9:01
    Модератор
  • Нет, вы не коректно ставите задачу. Если вы ищите переменную X, то регулярное выражение:

    \W?(X)\W?

    а если вы ищите переменную Xt, то регулярное выражение:

    \W?(Xt)\W?

    Как то так...

    24 июля 2012 г. 9:04
    Отвечающий
  • Нет, вы не коректно ставите задачу. Если вы ищите переменную X, то регулярное выражение:

    \W?(X)\W?

    а если вы ищите переменную Xt, то регулярное выражение:

    \W?(Xt)\W?

    Как то так...

    IsMatch по регулярному выражению \W?(X)\W? в формуле: Xt+9, выдаст true.
    24 июля 2012 г. 9:15
  • Тогда можно попробовать вот такое выражение:

    ([^\w\d]|^)(X)([^\w\d]|$)

    • Помечено в качестве ответа LIKORIS 24 июля 2012 г. 9:52
    24 июля 2012 г. 9:31
    Отвечающий
  • Тогда можно попробовать вот такое выражение:

    ([^\w\d]|^)(X)([^\w\d]|$)

    Как раз то, что нужно. Спасибо.
    24 июля 2012 г. 9:52
  • "IsMatch по регулярному выражению \W?(X)\W? в формуле: Xt+9, выдаст true." - но Вы же изначально задали такое условие, что переменная там только X, в этом случае это то самое выражение. В втором случае, когда переменные вида X***, шаблон уже другой. Вообщем меняется условие, меняется и шаблон. Поэтому с самого начала нужно точно определиться.
    24 июля 2012 г. 9:53
    Модератор
  • И всё же, не понятным осталось что конкретно нужно было Вам, как говорится проехали.
    24 июля 2012 г. 10:10
    Модератор
  • Нужно было проверять, есть ли в выражении конкретная переменная. Причем имя этой переменной известно. Имя может содержать буквы и цифры. Ну по крайней мере, я последнее выражение писал исходя из этих предпосылок.
    24 июля 2012 г. 10:18
    Отвечающий
  • Тогда последнее подходит только для одиночных переменных, на составных типа X2, Xt, оно работать не будет. Наверное топик-стартер несовсем правильно поставил задачу. Впрочем, раз это его устроит, то что сказать.
    24 июля 2012 г. 10:31
    Модератор
  • Самое забавное, что работает, просто для каждой переменной свое регулярное выражение:

    ([^\w\d]|^)(X2)([^\w\d]|$)

    ([^\w\d]|^)(Xt)([^\w\d]|$)

    24 июля 2012 г. 12:24
    Отвечающий
  • Привет.

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


    Для связи [mail]

    27 июля 2012 г. 8:54