Может ли regex использоваться для сравнения 2 чисел в строке? [Дубликат]

Это решило мою ошибку:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
    addPhotoBtn.setImage(pickedImage, for: .normal)
    dismiss(animated: true, completion: nil)


}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: nil)

}
2
задан Wai Ha Lee 16 September 2015 в 11:21
поделиться

3 ответа

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

string num="number1-number2";//where (number1 & number2)=numeric val
MatchCollection stringVal= Regex.Matches(num,@"\d+");
int num1=Convert.ToInt32(stringVal[0].Value);
int num2=Convert.ToInt32(stringVal[1].Value);
if(num1>=0 && num1<=int.MaxValue && num2>=num1 && num2<=int.MaxValue)
    return true;
else
   return false;

даст вам массив, содержащий числа

1
ответ дан debatanu 21 August 2018 в 01:33
поделиться
  • 1
    хорошо используя regex, мы не можем выполнить сравнение, все, что мы можем сделать, это совпадение и извлечение данных. поэтому, как только данные будут доступны, операцию сравнения следует позаботиться отдельно – debatanu 16 September 2015 в 11:21
  • 2
    в вашем образце num1 всегда так же, как num2 :-D – Grundy 16 September 2015 в 11:37

Решение

Можно проверить его с помощью regex - но вы должны предпочесть решение в коде, потому что оно будет намного быстрее. Этому регулярному выражению требуется много возврата. Единственное преимущество этого регулярного выражения состоит в том, что он работает для произвольной длины.

(?:^0+-\d+$)
|
(?:^(?>0*)(?<number>\d+)-(?>0*)\k<number>$)
|
(?:
    (?:^(?>0*)(?<length>\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+$)
    |
    (
        (?=^(?>0*)(?<o>\d)+-(?>0*)(?<-o>\d)*(?(o)(?!))$)
        ^
            (?>0*)
            (?<prefix>\d*)
            (?:(?<g0>0)|(?<g1>1)|(?<g2>2)|(?<g3>3)|(?<g4>4)|(?<g5>5)|(?<g6>6)|(?<g7>7)|(?<g8>8)|(?<g9>9))
            \d*
        -
            (?>0*)
            \k<prefix>
            (?(g0)[1-9]|(?(g1)[2-9]|(?(g2)[3-9]|(?(g3)[4-9]|(?(g4)[5-9]|(?(g5)[6-9]|(?(g6)[7-9]|(?(g7)[89]|(?(g8)9|(?!))))))))))
            \d*
        $
    )
)

Это соответствует для каждого x-y, где x <= y для положительных целых чисел, включая ледящие нули.

DEMO

Это не работает для символов.

Объяснение

Мне удалось создать регулярное выражение, которое соответствует x-y для всех x < y. Вопрос был x <= y. Поэтому я разделил вопрос на x = y | x < y.

Нам нужно обработать, что первое или оба числа содержат только нули, но это тривиально:

^0+-\d+$

Теперь случай x = y

^(?>0*)(?<number>\d+)-(?>0*)\k<number>$

Трудная часть - x < y.

  1. x меньше y, если x короче длины символа, чем y (фиксирующие нули захватываются атомной группой): ^(?>0*)(?<length>\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+ Эта первая группа захватывает целое число на один захват за цифру. После разделителя определение балансирующей группы очищает стек захвата и заставляет по меньшей мере еще одну цифру.
  2. Оба числа имеют одинаковую длину (если первое число больше, оно также больше и не должно совпадать). Чтобы гарантировать, что оба числа имеют одинаковую длину, я начал с положительного взгляда на утверждение, которое обеспечивает его таким же образом, как я тестировал более длинное число на шаге 1: (?=^(?>0*)(?<o>\d)+-(?>0*)(?<-o>\d)*(?(o)(?!))$). После этого алгоритм прост. Начните с начала. Если текущая цифра равна, перейдите к следующей цифре. Если текущий x -digit медленнее текущего y -digit, мы закончили и найдено совпадение. Если это медленнее, мы не должны совпадать. Это делается по этой схеме:
    ^
        (?>0*)   # cut out leeding zeros
        (?<prefix>\d*)
        .*
    -
        (?>0*)   # cut out leeding zeros
        \k<prefix>  # both numbers start with the same part
        .*
    $
    
    И теперь проверка на одну цифру. Есть только 10 возможностей [0-9]. Каждый из них захватывается одной группой: (?<g0>0)|(?<g1>1)|(?<g2>2)|(?<g3>3)|(?<g4>4)|(?<g5>5)|(?<g6>6)|(?<g7>7)|(?<g8>8)|(?<g9>9) Теперь мы можем использовать условия для проверки того, больше ли текущий y -digit, чем текущий x -digit. Отобразится для 0 и 1: (?<g0>0)|(?<g1>1): если для текущего x -digit соответствует 0, для текущего y -digit есть только [1-9]. Если 1 соответствует только [2-9], возможно. Это можно использовать в условии: (?(g0)[1-9]|...), что означает, что если g0 имеет захват [1-9], он должен совпадать, иначе остальное должно совпадать. Это комбинируется с: (?(g0)[1-9]|(?(g1)[2-9]|(?(g2)[3-9]|(?(g3)[4-9]|(?(g4)[5-9]|(?(g5)[6-9]|(?(g6)[7-9]|(?(g7)[89]|(?(g8)9|(?!)))))))))). Последний трюк заключается в том, что ни одна из групп g[0-8] не была сопоставлена ​​только g9, и нет большего количества цифр, и совпадение должно завершиться неудачно (?!).

Все это было объединено со всем регулярным выражением, которое соответствует x-y для всех x <= y.

3
ответ дан Vera rind 21 August 2018 в 01:33
поделиться

Вы не можете использовать регулярное выражение для сравнения извлеченных чисел. Вам нужно проанализировать значения с помощью int.TryParse и реализовать другие проверки, чтобы получить то, что вам нужно.

Предполагая, что в диапазонах есть только целые положительные числа , здесь String.Split и int.TryParse:

private bool CheckMyRange(string number_range, ref int n1, ref int n2)
{
    var rng = number_range.Split('-');
    if (rng.GetLength(0) != 2) 
       return false;

    if (!int.TryParse(rng[0], out n1))
       return false;
    if (!int.TryParse(rng[1], out n2))
       return false;
    if (n1 >= 0 && n1 <= int.MaxValue)
       if (n2 >= n1 && n2 <= int.MaxValue)
           return true;
    return false;
}

И назовите его например

int n1 = -1;
int n2 = -1;
bool result = CheckMyRange("1-2", ref n1, ref n2);
4
ответ дан Wiktor Stribiżew 21 August 2018 в 01:33
поделиться
  • 1
    Вы не можете использовать регулярное выражение для сравнения извлеченных чисел. Это неверно. Возможно. – Vera rind 16 September 2015 в 12:22
  • 2
    @Verarind: пусть OP и другие решают, что правильно для этой конкретной задачи. Я считаю, что регулярное выражение здесь не подходит. – Wiktor Stribiżew 16 September 2015 в 12:25
  • 3
    Да, я с вами, что регулярное выражение не подходит в этом случае. Использование вашего кода будет намного быстрее - но это возможно. – Vera rind 16 September 2015 в 12:29
Другие вопросы по тегам:

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