RegEx для поиска совпадений между кавычками - PullRequest
3 голосов
/ 01 июня 2019

Здесь я пытаюсь найти String в double quotes.

   List<String> getList(String value){
    String regex = "\"[^\"]*\"|[^,]+";
    List<String> allMatches = new ArrayList<String>();
    if (StringUtils.isNotBlank(value)) {
        Matcher m = Pattern.compile(regex).matcher(value);
        while (m.find() && StringUtils.isNotBlank(m.group())) {
            String str=m.group().replaceAll("^\"|\"$", "");
            allMatches.add(str.trim());
        }
    }
    return allMatches;
  }

  result = getList(400,test,\"don't split, this\",15);
  result have [400,test,don't split, this,15] all comma seperated string except inside quotes.

. Он хорошо работает для шаблона "", но не для “”."foo,bar", отличается от "foo,bar" здесь не работает регулярное выражение

Ответы [ 3 ]

1 голос
/ 01 июня 2019

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

(?:“[^“”]+”|"[^"]+"|(?<=,|^)[^“”,"]+(?=(?:,|$)))

Объяснение

  • (?: Группа без захвата
    • “[^“”]+” Вариант совпадения , затем не или и вариант совпадения
    • | или
    • "[^"]+" Матч, ", затем не " и снова "
    • | или
    • (?<=,|^) Укажите, что слева - запятая или начало строки
    • [^“”,"]+ Соответствует любому символу, не входящему в класс персонажа
    • (?=(?:,|$)) Подтвердите, что справа является запятой или концом строки
  • ) Закрыть группу без захвата

Regex demo | Java демо

Весь шаблон представляет собой чередование, которое имеет 3 варианта. Первые 2 варианта совпадают от открытия до закрытия цитаты.

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

1 голос
/ 01 июня 2019

Вы можете создать гибрид в стиле CSV, используя свой код Java, но регулярное выражение необходимо изменить.

Java

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{

    public static List<String> getList(String value)
    {
        String regex = "(?:(?:^|,|\\r?\\n)\\s*)(?:(?:(\"[^\"\\\\]*(?:\\\\[\\S\\s][^\"\\\\]*)*\"|“[^“”\\\\]*(?:\\\\[\\S\\s][^“”\\\\]*)*”))(?:\\s*(?:(?=,|\\r?\\n)|$))|([^,]*)(?:\\s*(?:(?=,)|$)))"; 
        List<String> allMatches = new ArrayList<String>();
        if ( value.length() > 0  )
        {
            Matcher m = Pattern.compile( regex ).matcher( value );
            while ( m.find() ) {
                String str = m.group(2);
                if ( str == null ) {
                    str = m.group(1);
                    str = str.replaceAll( "^[\"“”]|[\"“”]$", "" );
                }
                allMatches.add(str.trim());
            }
        }
        return allMatches;
    }


    public static  void main (String[] args) throws java.lang.Exception
    {
        List<String>  result = getList("400,test,\"QT_don't split, this_QT\",15");
        System.out.println( result );

        result = getList("500,test,“LQT_don't split, this_RQT”,15");
        System.out.println( result );

        result = getList("600,test,\"QT_don't split, this_QT\",15");
        System.out.println( result );

    }
}

https://ideone.com/b8Wnz9

Выход

[400, test, QT_don't split, this_QT, 15]
[500, test, LQT_don't split, this_RQT, 15]
[600, test, QT_don't split, this_QT, 15]

Regex Expanded

 (?:
      (?: ^ | , | \r? \n )          # Delimiter comma or newline
      \s*                           # leading optional whitespaces
 )
 (?:                           # Double Quoted field
      (?:
           "                             # Quoted string field ""
           (                             # (1), double quoted string data
                [^"\\]* 
                (?: \\ [\S\s] [^"\\]* )*
           )
           "

        |                              # or

           “                             # Quoted string field Left/right double quotes “”   
           (                             # (2), double quoted string data
                [^“”\\]* 
                (?: \\ [\S\s] [^“”\\]* )*
           )
           ”
      )
      (?:
           \s*                           # trailing optional whitespaces
           (?:
                (?= , | \r? \n )              # Delimiter ahead, comma or newline
             |  $ 
           )
      )
   |                              # OR
      ( [^,]* )                     # (3), Non quoted field
      (?:
           \s*                           # trailing optional whitespaces 
           (?:
                (?= , )                       # Delimiter ahead, comma
             |  $ 
           )
      )
 )
0 голосов
/ 01 июня 2019

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

Pattern regex = Pattern.compile("[\"\u201C](.*)[\"\u201D]");
List<> allMatches = new ArrayList<String>();
Matcher m = regex.matcher(value);
while (m.find()) {
    allMatches.add(m.group(1).trim());
}

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

...