У меня есть следующий текст:

Генеральный прокурор Уильям Барр сказал, что объем скомпрометированной информации «ошеломляет» и является крупнейшим нарушением в истории США. «Эта кража не только нанесла значительный финансовый ущерб Equifax, но и вторглась в частную жизнь многих, миллионов американцев и наложила значительные расходы и бремя на им, поскольку они должны были принять меры, чтобы защитить себя от кражи личных данных ", сказал г-н Барр.

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

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

(?<=[\\“|\\"])[A-Za-z0-9\.\-][A-Za-z\s,:\\’]+(?=[\”|\"])

Однако это будет включать в себя цитату «ошеломляющий», которая составляет всего 1 слово, поэтому ее следует игнорировать.

Я понимаю, что могу сделать это, повторив эту часть Regex 5 раз:

[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+[A-Za-z\s,:\\’]+

Однако мне интересно, есть ли более короткий и более краткий способ добиться этого? Возможно, заставляя \s в [] появляться как минимум 5 раз?

Спасибо

2
S.O.S 20 Фев 2020 в 01:57

2 ответа

Лучший ответ

Вам необходимо «развернуть» класс символов, вынув из него шаблон сопоставления пробелов и использовать шаблон [<chars>]+(?:\s+[<chars>]+){4,}. Обратите внимание, что здесь не следует использовать обходные пути, потому что " может быть как ведущим, так и конечным маркером, что может привести к нежелательным совпадениям. Вместо этого используйте группу захвата и получите доступ к ее значению через matcher.group(1).

Вы можете использовать

String regex = "[“\"]([A-Za-z0-9.-][A-Za-z,:’]*(?:\\s+[A-Za-z0-9.-][A-Za-z,:’]*){4,})[”\"]";

См. демонстрационную версию regex.

Затем просто возьмите значение группы 1:

String line = "Attorney General William Barr said the volume of information compromised was “staggering” and the largest breach in U.S. history.“This theft not only caused significant financial damage to Equifax but invaded the privacy of many, millions of Americans and imposed substantial costs and burdens on them as they had to take measures to protect themselves from identity theft,” said Mr. Barr.";
String regex = "[“\"]([A-Za-z0-9.-][A-Za-z,:’]*(?:\\s+[A-Za-z0-9.-][A-Za-z,:’]*){4,})[”\"]";
Matcher m = Pattern.compile(regex).matcher(line);
List<String> res = new ArrayList<>();
while(m.find()) {
    res.add(m.group(1));
}
System.out.println(res);

См. интерактивную демонстрацию Java.

Детали шаблона

  • [“"] - или "
  • ([A-Za-z0-9.-][A-Za-z,:’]*(?:\\s+[A-Za-z0-9.-][A-Za-z,:’]*){4,}) - группа 1: < UL>
  • [A-Za-z0-9.-][A-Za-z,:’]* - буквенно-цифровой код ASCII или . или -, а затем 0+ букв ASCII, ,, :, символов
  • (?:\s+[A-Za-z0-9.-][A-Za-z,:’]*){4,} - четыре или более < UL>
  • \s+ - 1+ пробелов
  • < Литий> < UL>
  • [A-Za-z0-9.-][A-Za-z,:’]* - буквенно-цифровой код ASCII или . или -, а затем 0+ букв ASCII, ,, :, символов
  • [”"] - " или
  • 3
    Wiktor Stribiżew 19 Фев 2020 в 23:18

    Вам нужно использовать правильное регулярное выражение, соответствующее вашему случаю.

    В приведенном ниже фрагменте кода соответствует текст в кавычках длиной 5 слов ,

        Pattern pattern = Pattern.compile("“((\\b\\w+\\b)+.?( *)){5,}”", Pattern.DOTALL);
    
        String input = "Attorney General William Barr said the volume of "+
        "information compromised was “staggering” and the largest breach in"+
         "U.S. history.“This theft not only caused significant financial "+
         "damage to Equifax but invaded the privacy of many, millions of"+
         "Americans and imposed substantial costs and burdens on them as "+
         "they had to take measures to protect themselves from identity theft,” said Mr. Barr.";
    
        Matcher m = pattern.matcher(input);
    
        while (m.find()) {
          String s = m.group();
          System.out.print(s);  
        }
    

    Примечание : вам нужно установить флаг utf8 для компиляции этих конкретных символов кавычек, " 'и' " '. Поэтому вместо javac TheClass.java используйте javac -encoding utf8 TheClass.java!

    1
    Themelis 19 Фев 2020 в 23:57