2015-03-09 4 views
3

Извинения за мою вопиющую нехватку знаний о регулярных выражениях, я понимаю много вопросов, возникающих здесь, но стараюсь, как я мог бы часами, я не могу понять это. В основном то, что я пытаюсь сделать, это заменить все вхождения шестизначных чисел (с дефисом или без них) в строке. Однако я не хочу заменять цифры, если им предшествуют определенные слова.Regex заменить только в случае, если не предшествует

Это решение Regular expression to match a line that doesn't contain a word? подходит к тому, что я ищу, но я не могу использовать его таким образом, чтобы это соответствовало моим требованиям.

Что мне нужно следующим образом: Для строки:

"Пользователь заплатил £ 43 на 23/05/14 на счет 123456 с 123456 проверка сделки: 123456."

Я хочу заменить только 6-значное число, которому не предшествует «проверка» или «транзакция:». То, что я пытался следующим образом:

\b[0-9]{2}-?[0-9]{2}-?[0-9]{2}\b 

(Это заменяет все 6 цифр номера)

Используя этот How do you replace a match, using regex, only if it is not preceded by a given character? ответ, я попытался

(^cheque\s[0-9]{2}-?[0-9]{2}-?[0-9]{2}\b) 

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

Методом проб и ошибок я нашел

(cheque\s+[0-9]{2}-?[0-9]{2}-?[0-9]{2}\b) 

заменит чек слово, за которым следует 6 значное число, так я получаю там - но мне нужно, чтобы отрицать это (и сделка с последующим 6 значное число) вместо этого вместо этого следует заменить 6-значное число , а не.

Этот ответ How to negate the whole regex? полезен при определении того, как отрицать выражение, но старайтесь, как я мог, я не могу найти, как заставить его работать для моей ситуации. Я попробовал

^(?!(?:((transaction\s+[0-9]{2}-?[0-9]{2}-?[0-9]{2}\b))|((cheque\s+[0-9]{2}-?[0-9]{2}-?[0-9]{2}\b)))$).*$ 

но это заменило целую цепочку!

Любая помощь на это очень ценится.

Спасибо.

+2

Просьба уточнить. На каком языке вы используете? Кроме того, если вы используете стандартный «заменить все», вы не можете заменить некоторые совпадения. Вы можете изменить регулярное выражение, чтобы НЕ совпадать с ними (выполнить требование) или выполнить итерацию по совпадениям и изучить их с помощью дополнительного кода. Не соответствует ли их достаточным для ваших нужд? – Necreaux

+0

Вы можете сделать это только в том случае, если ваш механизм регулярных выражений поддерживает [негативный внешний вид] (http://www.regular-expressions.info/lookaround.html). – m0skit0

+0

Спасибо за очень быстрые ответы! Я использую C#, и я застрял в визуальной студии 2005. – Misemefein

ответ

10

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

(?<!(?:cheque|transaction:)\s*)\d{2}-?\d{2}-?\d{2}\b 

Объяснение:

  • (?<! ...) Отрицательное утверждение с просмотром назад (матч ничего не предшествовало этим)
  • (?:cheque|transaction:)\s* без захвата группы "чек" или "сделка:" за которым следует любое количество пробелов
  • \d{2}-?\d{2}-?\d{2}\b Шестьзначное число, возможно, переносимое, заканчивающееся словом bounda ry
+0

Большое вам спасибо tzaman. Я понял это вчера вечером, и ваше решение очень близко к тому, что я придумал: – Misemefein

0

Большое спасибо @tzaman за ваш ответ - с какой-то головкой, царапиной, пробкой и ошибкой, а также с сообщением от коллеги, который я выяснил вчера вечером, и придумал следующее. (Я добавлю много случаев, потому что возможно пользователь будет вводить такие вещи, как номер чека/проверить нет и т.д., но они просто дополнительные условия. -. Ниже основная часть решаемой задачи)

(?<!         
    (
    (cheque\s{0,}:{0,1}\s{0,}) 
    | 
    (transaction\s{0,}:{0,1}\s{0,}) 
) 
) 
(
    [0-9]{6} 
    | 
    ([0-9]{2}[0-9]{2}-[0-9]{2}) 
) 

Еще раз спасибо.

Смежные вопросы