2012-01-19 5 views
2

Я в строгой среде Java.Java regex match против src = "abc" или src = 'abc'

Таким образом, вопрос не так прост, как в тите, я не пытаюсь решить проблему, которую я имею, это более теоретически для лучшего знания.

Меня интересует совпадение с src с двойной или простой цитатой, но если это двойная кавычка, она также должна быть закрыта двойной кавычкой, и это также относится к простой цитате.

Я знаю, что я могу повторить регулярное выражение само по себе, а именно:

String str = "src=\"hello/\" ... src='hello/' ..." 

println str.replaceAll ("src=((\"[^\"]+\")|('[^']+'))", "src=$1") 

То, что я хотел бы сделать это как:

println s.replaceAll ("src=([\"'][^\"']+[\"'])", "src=$1") 

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

Вопрос 2:

Можно ли иметь это replaceAll с тем же типом цитаты, который был найден? Можно ли сказать, для этого матча, заменить на это2, для этого заменить на это2. Как вы можете выполнить это без создания новой строки каждый раз?

Edit для Алана Более того, пример вопроса два:

более
println "one ... two".replaceAll("(one)", "1").replaceAll("(two)", "2"); 

вдоль этих линий (не верно)

println "one ... two".replaceMyMatches("(one)[^\\w]+(two)", "\$1{1}, \$2{2}") // prints string : one{1}, two{2} 

То, что я хочу, это строка: 1, 2

Ответ на первый вопрос, полученный и измененный от черной панды и Джеффа Уолкера:

String str = "src=\"1.png\" ... src='2.jpeg' ... src=\"3.p'ng\" ... src='4.jpe\"g' ... src='' ... src=\"\" ..." ; 

String regex = "src=(['\"])(.+?)\\1"; // closes with the quote that is in group 1 

println str.replaceAll(regex, '''src=$1../new_path/$2$1''') 

выплевывает:

src="../new_path/1.png" ... src='../new_path/2.jpeg' ... src="../new_path/3.p'ng" ... src='../new_path/4.jpe"g' ... src='' ... src="" ... 

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

Обратите внимание на оригинальные цитаты.

Ответьте на вопрос два см черный панда

+0

Я не понимаю второй вопрос. Есть примеры? –

+0

@AlanMoore См. Отредактированный вопрос – momomo

ответ

2

Мой ответ на вопрос 1 изначально был неверным. Вот обновленная версия.

Чтобы ответить на вопрос 1..See если это регулярное выражение позволяет: Узор:

src=(['"])(.*?)\1 

Код ниже объясняет каждую часть.

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Regex { 

    public static void main(String[] args) 
    { 
     final String regex = "src=(['\"])" // the ' or the " is in group 1 
       + "(.*?)" // match any character in a non-greedy fashion 
       + "\\1"; // closes with the quote that is in group 1 
     Pattern p = Pattern.compile(regex); 

     Matcher m = p.matcher("src=\"hello/\" ... src='goodbye/' ... " 
       + "src='this has a \" in it'"); 

     while (m.find()) 
     { 
     System.out.println("\nfound!"); 
     System.out.println("The quote was a " + m.group(1)); 
     System.out.println("the text was = " + m.group(2)); 
     } 
    } 
} 

Это дает выход:

found! 
The quote was a " 
the text was = hello/ 

found! 
The quote was a ' 
the text was = goodbye/ 

found! 
The quote was a ' 
the text was = this has a " in it 

Что касается второго вопроса, то вам придется использовать немного больше кода, чем это. Вы создаете свой собственный StringBuffer и добавляете по мере продвижения. Я использовал карту, чтобы провести замену:

public static void question2() 
    { 
     Pattern p = Pattern.compile("one|two"); 
     Map<String, String> replacements = new HashMap<String, String>(); 

     replacements.put("one", "1"); 
     replacements.put("two", "2"); 

     StringBuffer result = new StringBuffer(); 

     String text = "one ... two"; 

     Matcher m = p.matcher(text); 

     while (m.find()) 
     { 
     m.appendReplacement(result, replacements.get(m.group())); 
     } 

     m.appendTail(result); 

     System.out.println(result.toString()); 

    } 

Воспроизводит:

1 ... 2 
+0

Удивительно! Я предполагаю, что вопрос 2 надуман? – momomo

+0

Запустили ли вы это? У меня есть компиляция вашего регулярного выражения в части 1. Я буду продолжать пытаться выяснить, где моя проблема. –

+0

Да, я использую JDK 6 на Netbeans 6.9 .1 –

2

Регулярное выражение для вопроса 1 является:

src=(['"])hello\1 (двойной обратный слэш для строки Java)

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

Таким образом, для более общем случае, мне нравится:

^src=(['"])(.*?)\1$

Тогда замена может быть что-то вроде:

String regex = "^src=(['\"])(.*?)\\1$"; 
String newthing = "src=$2"; 

Это то, что вы хотели? В основном, чтобы стричь кавычки, соблюдая их соответствие?

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

Вместо замены вам нужно будет проверить группу 2 и «утвердить», что группа 1 не существует. Заметил, что я добавил начальные и конечные привязки к регулярному выражению.

Так что-то вроде:

Pattern p = Pattern.compile("^src=(['\"])(.*?)\\1$"); 
Matcher m = p.matcher("src=\"what's up?\""); 
if (m.matches()) { 
    if (m.group(2).contains(m.group(1))) { 
     // fail, doesn't match 
    } 
} 
// success, follows all of the rules 

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

+1

+1 Приятный и аккуратный! –

+0

Плакат хочет иметь возможность включать кавычки другого типа в строку. Он хочет иметь возможность разобрать src = 'это «некоторый текст» –

+2

А теперь я вижу. Я уверен, что это невозможно с одним регулярным выражением. Обновление моего ответа снова .... –

1

Вы могли бы попробовать что-то вроде этого

String str = "src=\"hello/\" ... src='hello/' ..."; 

System.out.println(str.replaceAll("src=([\"'])(.*?)\\1", "src='$2'")); 

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

0

По первому вопросу вы можете использовать это регулярное выражение:

"([\"'])(?:(?!\\1).)*\\1" 

Вторая часть не имеет чистого регулярного выражения - по крайней мере, не на Java. См. this answer для Java-способа. Так, например, если у вас есть таблица вроде этого:

{ "one" => "1", "two" => "2" } 

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

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