Java Regex: как захватить несколько совпадений в одной строке - PullRequest
5 голосов
/ 19 сентября 2011

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

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

Например, у меня естьэта строка ввода:

1234567 100,110,116,129,139,140,144,146 http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All&viewItems=25&subCatView=true   ISx20070515x00001a          http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=Screen+Refresh+Rate%7C120HZ&sName=View+All&subCatView=true 0   2819357575609397706

И меня интересуют эти строки:

Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.

Screen+Refresh+Rate%7C120HZ

Ответы [ 6 ]

6 голосов
/ 19 сентября 2011

Предполагая, что известным началом является filter=**, шаблон регулярного выражения (?:filter=\\*\\*)(.*?)(?:&) должен получить то, что вам нужно.Используйте Matcher.find(), чтобы получить все вхождения шаблона в заданной строке.Используя предоставленную вами строку теста, следующее:

final Pattern p = Pattern.compile("(?:filter=\\*\\*)(.*?)(?:&)");
final Matcher m = p.matcher(testString);
int cnt = 0;
while (m.find()) {
    System.out.println(++cnt + ": G1: " + m.group(1));
}

Будет выводить:

1: G1: Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.
2: G1: Screen+Refresh+Rate%7C120HZ**
2 голосов
/ 19 сентября 2011

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

String url = URLDecoder.decode("http://www.gold.com/shc/s/c_10153_12605_" +
            "Computers+%26+Electronics_Televisions?filter=Screen+Refresh+Rate" +
            "%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All&viewItems=25&subCatView=true"
            ,"utf-8");
Pattern amp = Pattern.compile("&");
Pattern eq = Pattern.compile("=");
Map<String, String> params = new HashMap<String, String>();
String queryString = url.substring(url.indexOf('?') + 1);
for(String param : amp.split(queryString)) {
    String[] pair = eq.split(param);
    params.put(pair[0], pair[1]);
}
for(Entry<String, String> param : params.entrySet()) {
    System.out.format("%s = %s\n", param.getKey(), param.getValue());
}

выход

subCatView = true
viewItems = 25
sName = View All
filter = Screen Refresh Rate|120HZ^Screen Size|37 in. to 42 in.
1 голос
/ 19 сентября 2011

Использование регулярного выражения (?<=filter=\*{0,2})[^&]*[^&*]+ в java:

Pattern p = Pattern.compile("(?<=filter=\\*{0,2})[^&]*[^&*]+");
String s = "1234567 100,110,116,129,139,140,144,146 http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All**&viewItems=25&subCatView=true   ISx20070515x00001a          http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ**&sName=View+All&subCatView=true 0   2819357575609397706";
Matcher m = p.matcher(s);
while (m.find()) {
    System.out.println(m.group());
}

EDIT:

Добавлен [^&*]+ в конец регулярного выражения, чтобы исключить включение ** во второй матч.

EDIT2:

Изменено регулярное выражение для использования lookbehind.

1 голос
/ 19 сентября 2011

в вашем примере иногда стоит "**" в конце перед "&". но в основном (при условии, что «filter =» - это шаблон запуска, который вы ищете), вы хотите что-то вроде:

"filter=([^&]+)&"

0 голосов
/ 19 сентября 2011

вы ищете строку, которая следует за «filter =» и игнорирует первое «*» и заканчивается первым «&». Вы можете попробовать следующее:

String str = "1234567 100,110,116,129,139,140,144,146 http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All**&viewItems=25&subCatView=true   ISx20070515x00001a          http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ**&sName=View+All&subCatView=true 0   2819357575609397706";
    Pattern p = Pattern.compile("filter=(?:\\**)([^&]+?)(?:\\**)&");

    Matcher matcher = p.matcher(str);
    while(matcher.find()){
        System.out.println(matcher.group(1));
    }
0 голосов
/ 19 сентября 2011

Требуемое регулярное выражение:

Screen\+Refresh\+Rate[^&]*

Вы можете использовать Matcher.find(), чтобы найти все совпадения.

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