Как мне сопоставить ни одно, одно или два значения в одной строке? - PullRequest
2 голосов
/ 17 декабря 2010

У меня есть строка, которая не может содержать ни одного, ни одного, ни двух значений.В случае, если есть два значения, они разделяются двоеточием :, также, если первое значение должно быть пустым, второе (единственное значение) будет начинаться с двоеточия.

Первое значение может быть составленопрактически любых буквенно-цифровых и специальных символов, второе значение только буквенно-цифровых символов.Поэтому двоеточие не является отдельным разделителем.

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

Мой фактический код выглядит следующим образом:

if ($string =~ m/^(.+)(\:(\w+)|)$/){  
    $value1 = $1 || '';    
    if ($3){$value2 = $3}
}

Этот работает для пустой строки, только первое значение, два значения без двоеточия в первом значении.

Редактировать :

Строка может быть:

  • Hello World! (только одно значение: value1 = 'Hello World!')
  • This is a test:123 (два значения: value1 = 'Это тест' value2 = '123')
  • :Banana (только одно значение: value2 = 'Banana')
  • T3-76: (только одно значение: value1 = 'T3-76:')
  • Book:Title:Mysql (два значения: value1 = 'Book: Title' value2 = 'Mysql')

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

Edit2

Если это облегчает, код можно изменить на , а не соответствует пустой строке.

У кого-нибудь есть идеи?

Ответы [ 4 ]

4 голосов
/ 17 декабря 2010

Возможно использовать split с отрицательным прогнозным утверждением:

my ($a, $b) = split(/:(?!.*:)/, $string);

Обратите внимание, что пустые значения могут быть либо undef, либо пустой строкой.

1 голос
/ 17 декабря 2010

Попробуйте это:

^((?:(?!:[\w]*$).)*)(?::([\w]+)?)?$
1 голос
/ 17 декабря 2010

Если я правильно понимаю, то толкование неоднозначно.Рассмотрим «1: 2».Это можно интерпретировать как первое значение, равное 1, второе значение как 2. Однако, поскольку первое значение может содержать специальные символы (такие как «:»), это также может быть интерпретировано как просто первое значение, равное «1: 2».

Как вы ожидаете, что ваш «переводчик» будет работать в этом случае?

РЕДАКТИРОВАТЬ:

Вы думали об использовании сплит?Он вернет массив.

Если массив пуст => строка была пуста.

Если массив имеет размер один => первый элемент в массиве имеет значение1

Если массив имеет несколько элементов => последний элементв массиве это значение2, а все остальные элементы до того, как это объединено, является значением 1.

Помогает ли это?

0 голосов
/ 18 декабря 2010

Я бы подумал сделать это с if, а не как одно регулярное выражение, делающее все.Может быть что-то вроде:

if ( m/^(.*):([^:]*)$/ ) { $value1 = $1; $value2 = $2; }
else { $value1 = $_; $value2 = ''; }

Важно ли, чтобы значение-2 было только буквенно-цифровым или более слабый (что угодно, не двоеточие) тест в порядке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...