diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/JsonHelper.cs b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/JsonHelper.cs index fc23a6de5b..3cff93493e 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/Helpers/JsonHelper.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/Helpers/JsonHelper.cs @@ -24,9 +24,14 @@ namespace AdvancedPaste.Helpers private static readonly char[] CsvDelimArry = [',', ';', '\t']; private static readonly Regex CsvSepIdentifierRegex = new Regex(@"^sep=(.)$", RegexOptions.IgnoreCase); - // Split on every occurrence of the delimiter except if it is enclosed by " and ignore two " as escaped " + // CSV: Split on every occurrence of the delimiter except if it is enclosed by " and ignore two " as escaped " private static readonly string CsvDelimSepRegexStr = @"(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"; + // CSV: Regex to remove/replace quotation marks + private static readonly Regex CsvRemoveSingleQuotationMarksRegex = new Regex(@"^""(?!"")|(?(); + var csv = new List>(); string[] lines = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); @@ -153,7 +158,8 @@ namespace AdvancedPaste.Helpers // and if every line contains no or an even count of quotation marks. if (Regex.Count(line, delim + CsvDelimSepRegexStr) == delimCount && int.IsEvenInteger(line.Count(x => x == '"'))) { - csv.Add(Regex.Split(line, delim + CsvDelimSepRegexStr, RegexOptions.IgnoreCase)); + string[] dataCells = Regex.Split(line, delim + CsvDelimSepRegexStr, RegexOptions.IgnoreCase); + csv.Add(dataCells.Select(x => ReplaceQuotationMarksInCsvData(x))); } else { @@ -244,5 +250,26 @@ namespace AdvancedPaste.Helpers throw new FormatException("Invalid CSV format: Failed to detect the delimiter."); } } + + /// + /// Remove and replace quotation marks used as control sequences. (Enclosing quotation marks and escaping quotation marks.) + /// + /// CSV cell data to manipulate. + /// Manipulated string. + private static string ReplaceQuotationMarksInCsvData(string str) + { + // Remove first and last single quotation mark (enclosing quotation marks) and remove quotation marks of an empty data set (""). + str = CsvRemoveSingleQuotationMarksRegex.Replace(str, string.Empty); + + // Remove first quotation mark if followed by pairs of quotation marks + // and remove last quotation mark if precede by pairs of quotation marks. + // (Removes enclosing quotation marks around the cell data for data like /"""abc"""/.) + str = CsvRemoveStartAndEndQuotationMarksRegex.Replace(str, string.Empty); + + // Replace pairs of two quotation marks with a single quotation mark. (Escaped quotation marks.) + str = CsvReplaceDoubleQuotationMarksRegex.Replace(str, "\""); + + return str; + } } }