9

I have created a function wherein I split a string from the csv filecsvAsString.split('\n') . It is working when the string is not so big. But when I try to split a very large string, an error will occur

regex too complicated

what I want to do is to catch if an error occur during the split process. How will I do it ? I've tried to use try and catch but the problem still occur. Is there any other possible solution?

3
  • Fields can contain embedded line breaks in csv files.
    – martin
    Jul 28, 2015 at 2:33
  • @martin I didn't understand your purpose. Actually I want to use split because I only need to get the first row. But my main issue here is to trap the possible error occured.
    – Hope
    Jul 28, 2015 at 2:37
  • That was just a warning that with using split('\n'), you won't get the entire line if one of the fields has a line break in it.
    – martin
    Jul 28, 2015 at 2:39

1 Answer 1

23

Not a catch per say (IIRC you cannot catch it, especially if Catch Exception did not work) but will solve the problem of regex to complex, use a custom iterator:

CLASS

public with sharing class Utility_RowIterator implements Iterator<String>, Iterable<String>
{
   private String m_Data;
   private Integer m_index = 0;
   private String m_rowDelimiter = '\n';
    
   public Utility_RowIterator(String fileData)
   {
      m_Data = fileData; 
   }
   public Utility_RowIterator(String fileData, String rowDelimiter)
   {
      m_Data = fileData; 
      m_rowDelimiter = rowDelimiter;
   }
    
   public Boolean hasNext()
   {
      return m_index < m_Data.length() ? true : false;
   }
   public String next()
   {     
      Integer key = m_Data.indexOf(m_rowDelimiter, m_index);
       
      if (key == -1)
        key = m_Data.length();
             
      String row = m_Data.subString(m_index, key);
      m_index = key + 1;
      return row;
   }
   public Iterator<String> Iterator()
   {
      return this;   
   }
}

CODE

Utility_RowIterator r = New Utility_RowIterator(csv,'\n'); //Replace \n with whatever delineates your row

String firstRow;
if(r.hasNext()) firstRow = r.next();

TEST CLASS (Provided by @KateFedchenko)

@isTest static void testUtilityRowIterator() {
    String csv = '"FirstName", "LastName"\n"TestName1", "Test1"\n"TestName2", "Test2"';
    List<String> names = new List<String>();
    UtilityRowIterator rowIterator = new UtilityRowIterator(csv, '\n');
    Iterator<String> iterator = rowIterator.iterator();
    while (iterator.hasNext()) {
        names.add(iterator.next());
    }
    System.assertEquals('"TestName1", "Test1"', names[1]);
}
9
  • I've tried this , and i think this is the answer of my problem. Thank you...
    – Hope
    Jul 28, 2015 at 5:29
  • @Hope - Glad it worked for you......
    – Eric
    Jul 28, 2015 at 5:31
  • 1
    Eric - although I voted this up ?years? ago, I had occasion to need this again and it was super helpful
    – cropredy
    Apr 3, 2020 at 17:57
  • 1
    Eric - your solution was incredibly helpful. I am looking to parse a CSV file and all of the CSVIterators I found did not account for the -1 key value that your code accounts for when firing next(). Much appreciated!!
    – David
    May 5, 2022 at 12:54
  • 1
    Eric provided an excellent solution to the problem that was solved thanks to his code. I do not have enough reputation to comment him, but I want to contribute at least a little bit with the test method for his class that covers 100% of lines. May 20, 2022 at 8:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .