Regex для удаления запятой в строке, когда она заключена в кавычки - PullRequest
4 голосов
/ 12 марта 2009

Мне нужно удалять запятые внутри строки, только если они заключены в кавычки.

пример:

String a = "123, \"Anders, Jr.\", John, john.anders@company.com,A"

после замены должно быть

String a = "123, Anders Jr., John, john.anders@company.com,A"

Можете ли вы дать мне пример кода Java для этого?

Большое спасибо,

Lina

Ответы [ 10 ]

2 голосов
/ 13 марта 2009

Есть две основные проблемы с принятым ответом. Во-первых, регулярное выражение "(.*)\"(.*),(.*)\"(.*)" будет соответствовать всей строке, если оно соответствует чему-либо, поэтому оно удалит не более одной запятой и двух кавычек.

Во-вторых, ничто не может гарантировать, что запятая и кавычки будут частью одного поля; учитывая ввод ("foo", "bar"), он вернет ("foo "bar). Он также не учитывает символы новой строки или экранированные кавычки, которые разрешены в указанных полях.

Вы можете использовать регулярные выражения для анализа данных CSV, но это гораздо сложнее, чем большинство людей ожидают. Но зачем бороться с этим, когда , как указал Бобинс , есть несколько бесплатных библиотек CSV для скачивания?

2 голосов
/ 13 марта 2009

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

boolean deleteCommas = false;
for(int i=0; i > a.length(); i++){
    if(a.charAt(i)=='\"'){
        a = a.substring(0, i) + a.substring(i+1, a.length());
        deleteCommas = !deleteCommas;
    }
    if(a.charAt(i)==','&&deleteCommas){
        a = a.substring(0, i) + a.substring(i+1, a.length());
    }
}
2 голосов
/ 12 марта 2009

Судя по вашему примеру, вам также нужно удалить кавычки.

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

"[^"]*"

затем удалите окружающие кавычки и замените запятые. Есть ли другие персонажи, которые вызывают беспокойство? Можно ли экранировать символы в кавычках, например. как ‘" "’?

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

1 голос
/ 12 марта 2009

Это похоже на строку из файла CSV, анализ которого через любую разумную библиотеку CSV автоматически решит эту проблему для вас. По крайней мере, читая указанное значение в одном «поле».

1 голос
/ 12 марта 2009

Должно работать:

s/(?<="[^"]*),(?=[^"]*")//g
s/"//g
0 голосов
/ 24 сентября 2015

Мой ответ не является регулярным выражением, но я считаю, что он проще и эффективнее. Измените строку на массив символов, затем просмотрите каждый символ. Следите за четных или нечетных котировок. Если нечетное количество кавычек и у вас запятая, не добавляйте ее. Должно выглядеть примерно так.

public String removeCommaBetweenQuotes(String line){


    int charCount = 0;
    char[] charArray = line.toCharArray();
    StringBuilder newLine = new StringBuilder();

    for(char c : charArray){

        if(c == '"'){
            charCount++;
            newLine.append(c);
        }

        else if(charCount%2 == 1 && c == ','){
            //do nothing
        }

        else{
            newLine.append(c);
        }


    }

    return newLine.toString();


}
0 голосов
/ 23 июня 2009

Следующий perl работает в большинстве случаев:

open(DATA,'in/my.csv');
while(<DATA>){
  if(/(,\s*|^)"[^"]*,[^"]*"(\s*,|$)/){
    print "Before: $_";
    while(/(,\s*|^)"[^"]*,[^"]*"(\s*,|$)/){
      s/((?:^|,\s*)"[^"]*),([^"]*"(?:\s*,|$))/$1 $2/
    }
    print "After: $_";
  }
}

Он ищет:

  • (запятая плюс дополнительные пробелы) или начало строки
  • цитата
  • 0 или более не кавычек
  • запятая
  • 0 или более не кавычек
  • (необязательные пробелы плюс запятая) или конец строки

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

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

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

0 голосов
/ 23 апреля 2009

Более простой подход - заменить совпадения этого регулярного выражения:

("[^",]+),([^"]+")

По этому:

$1$2
0 голосов
/ 23 апреля 2009

Это отлично работает. '<' вместо '>'

boolean deleteCommas = false;
for(int i=0; i < text.length(); i++){
    if(text.charAt(i)=='\''){
        text = text.substring(0, i) + text.substring(i+1, text.length());
        deleteCommas = !deleteCommas;
    }
    if(text.charAt(i)==','&&deleteCommas){
        text = text.substring(0, i) + text.substring(i+1, text.length());
    }
}
0 голосов
/ 12 марта 2009

Возможно, это крайне неэффективно, но, похоже, работает.

import java.util.regex.*;

StringBuffer ResultString = new StringBuffer();

try {
    Pattern regex = Pattern.compile("(.*)\"(.*),(.*)\"(.*)", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    Matcher regexMatcher = regex.matcher(a);
    while (regexMatcher.find()) {
        try {
            // You can vary the replacement text for each match on-the-fly
            regexMatcher.appendReplacement(ResultString, "$1$2$3$4");
        } catch (IllegalStateException ex) {
            // appendReplacement() called without a prior successful call to find()
        } catch (IllegalArgumentException ex) {
            // Syntax error in the replacement text (unescaped $ signs?)
        } catch (IndexOutOfBoundsException ex) {
            // Non-existent backreference used the replacement text
        } 
    }
    regexMatcher.appendTail(ResultString);
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...