2013-09-03 5 views
2

Я пытаюсь написать регулярное выражение, которое должно отображать строку до той части, где она находит пробел, а затем дефис «-». Если он не находит этот шаблон, он должен отображать всю строку. в строке могут быть другие пробелы или дефисы.Регулярное выражение: соответствие строки до определенных символов

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

^([^ ]+[^-]+)(-).+ 

входных строк и совпадающих в группе 1 выше регулярного выражения -

  • Лондона-Париж Токио -> Лондон-Париж
  • Лондон Мадрид - Париж-Берлин-Рим - Токио -> Лондон Мадрид
  • Лондон Париж - Берлин Токио -> Лондон Париж
  • Лондон Париж -> Лондон Париж

Однако выше регулярное выражение не соответствует следующий случай:

  • Лондон Париж (некоторые-текст) - берлин/Токио

Я пробовал несколько вариантов регулярного выражения, также с отрицательным взглядом, но безрезультатно.

Любая помощь будет оценена! Благодаря

EDIT:Спасибо всем за полезные и пояснительные предложения, однако ответ на @Vince ниже работало идеально подходит для моих потребностей. Я добавил комментарий ниже

ответ

2

Ваше регулярное выражение соответствует

start of the line 
followed by one or more non-whitespaces 
followed by one or more non-hyphens 
followed by whitespace 
followed by hyphen 
followed by one or more anything 

Это не то, что вы хотите. Вы хотите

one or more anything 
followed by whitespace 
followed by hyphen 
followed by one or more anything 

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

^(.+)\s-.+$ 

Если вы хотите, чтобы соответствовать первой комбинации \s- вы можете использовать нежадным +?, т.е.

^(.+?)\s-.+$ 

Хотя это будет только соответствовать, если в строке есть -. Если вы хотите соответствовать, даже если это не так, вы должны сделать эту часть опциональной.

^(.+?)(\s-.+)?$ 

Теперь регулярное выражение будет соответствовать любой строке, и если строка содержит - она сохранит часть до этого в $ 1.

+0

Спасибо @Vince. Ваш последний вариант кажется применимым к моему делу, я попробую ваше регулярное выражение! – nkrgupta

+0

@ M42, пожалуйста, определите «Не работает», потому что я тестировал его, и он работает для меня с этими двумя строками. – Vince

+0

@nkrgupta Я был бы признателен, если бы вы приняли мой ответ, если это решение, с которым вы идете :) – Vince

3

я бы использовать не жадный cuantifier и делать двойную проверку после него, либо пробел и дефис или в конце строки:

#!/usr/bin/env perl 

use warnings; 
use strict; 

while (<DATA>) { 
     m/^(.*?)(?:\s+-|$)/ && print "$1\n"; 
} 

__DATA__ 
London-Paris Tokyo 
London Madrid - Paris-Berlin-Rome - Tokyo 
London Paris - Berlin Tokyo 
London Paris 
London Paris (some-text) - berlin/tokyo 

Это дает:

London-Paris Tokyo 
London Madrid 
London Paris 
London Paris 
London Paris (some-text) 
+0

Начало символа линии:^необходимо в этом регулярном выражении? – user4035

+0

@ user4035: Не совсем, но и не наносит вреда. – Birei

+0

@Birei - Спасибо за ответ! Он отлично работает как решение Perl (это то, что я пытаюсь сделать в качестве первого шага), но когда я реплицирую регулярное выражение в JasperReport .jrxml-файле (он использует компиляцию Java и, я думаю, совместим с стилями regex Perl), я получить ошибки компиляции. Любая идея, что там нужно изменить? – nkrgupta

0

Я думаю, что у вас есть проблемы в обратном направлении. Вы пытаетесь найти текст перед вашим пространством/дефисом и извлечь его, когда вам нужно найти текст после пробела/дефиса и заменить его ничем. Таким образом, действие выполняется только в том случае, если регулярное выражение соответствует другому, вы сохраняете исходный текст. Я не программист Perl, но я думаю, что вы хотите что-то вроде этого:

$string =~ s/ -.*$//; 
+0

Привет, Дейв, спасибо за ответ! вы правы, я на самом деле пытаюсь сделать то, что вы сказали, но каким-то образом до сих пор частично успешно. Попробуй также свое регулярное выражение. – nkrgupta

2

Вы также можете использовать что-то вроде этого (Java код):

String str = "London Paris"; 
String substr[] = str.split("\\s+-"); 
return substr[0]; 

Он работает для случая использования:

London-Paris Tokyo --> London-Paris 
London Madrid - Paris-Berlin-Rome - Tokyo --> London Madrid 
London Paris - Berlin Tokyo --> London Paris 
London Paris --> London Paris 

EDIT: Использование ReplaceAll:

str.replaceAll("\\s*-.*", "") 
+0

Я фактически использую инструмент, называемый дизайнером iReport, который использует Groovy, и у меня есть возможность использовать только условную оценку (условие? «True»: «false») в файле .jrxml. Поэтому я пытаюсь использовать функцию replaceAll Java с регулярным выражением для вывода строки с изменениями, если выполняются какие-либо условия (если строка содержит пробел, за которой следует дефис, напечатайте только часть до 1-го такого появления «-»,) – nkrgupta

+0

Не уверен, что я получу часть replaceAll, но я также добавил код для выполнения задачи с помощью replaceAll. – Averroes

+0

Спасибо @Averroes. ваше решение с заменой All работает в большинстве случаев, за исключением тех, где есть дефис, не следуя пробелу. В любом случае есть отрезки перед дефисом, чего не должно быть. Решение Винса выше, работает для меня пока.Но мне было бы интересно узнать, можете ли вы изменить решение replaceAll, чтобы охватить все случаи! – nkrgupta

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