8

I wonder if it's possible to use the apex public String[] split(String regExp) method to split a string by the newline characters. The string being a csv file created on the Windows platform.

I tried several apex expressions in different forms and shapes, but it either doesn't work for me or it probably leaves the carriage return symbol within the resulting strings (if I try to match a resulting string against another clean string it should match, they don't match).

4
  • Can you provide more detail about where you are getting your input from, possibly including an example?
    – Adrian Larson
    Commented Feb 16, 2016 at 17:19
  • @AdrianLarson I'm getting the input from the CSV file created with Microsoft Excel.
    – Andrew
    Commented Feb 16, 2016 at 17:22
  • 1
    You can use \\n or \\r\\n to split in windows Commented Feb 16, 2016 at 17:25
  • Did you ever get this working?
    – Adrian Larson
    Commented Mar 9, 2016 at 21:15

5 Answers 5

7

Try \n:

myInput.split('\n');

If your input uses \r\n, that is another common option.

myInput.split('\r\n');
5
  • I have already tried those two.
    – Andrew
    Commented Feb 16, 2016 at 17:18
  • It accepts a regex, which in apex needs an extra escape. E.g. \\r\\n Commented Feb 17, 2016 at 4:07
  • @ca_peterson Yeah that's what I thought too, but if I debug 'a\nb\nc\nd'.split('\n') I get a list with the correct 4 elements. Why does that work?
    – Adrian Larson
    Commented Feb 17, 2016 at 4:14
  • Good question, I'm curious myself why this works. My understanding is that it shouldn't, as Andrejs observed. Commented Feb 17, 2016 at 4:24
  • The reason "\n" works in the regular expression in APEX is because it is translated to the actual linefeed character, which technically still matches a newline so the regEx passes. You can also use "\\n" to symbolize the regEx value of "\n" instead of the ASCII character of newline.
    – Paul N
    Commented Apr 29, 2021 at 14:08
5

In windows you can use split method in other format. Use below example

variable.split('\\n');

or

variable.split('\\r\\n');

Explanation:

Since Salesforce implements Java Pattern class, the meta-characters that have a special meaning are needs to be escaped. Meta <([{\^-=$!|]})?*+.>.

Here three back slashes are used instead of one is because the meta-character needs to be escaped with a "\" but since "\" is also a meta-character, you need to escape it again with another "\".

Useful Links: Java Regex Tutorial | String.split Blogpost

6
  • Since you're the first one to realize it...might be worth explaining why you need to escape \ characters.
    – Adrian Larson
    Commented Feb 16, 2016 at 17:59
  • 2
    And this is not just for windows, btw. Commented Feb 16, 2016 at 18:41
  • In windows, backslash character () is know as escape sequence. Windows use the file system in backslash character. So whenever we need to use any combination of backslash, we will put extra backslash so that window system can understand it. Commented Feb 16, 2016 at 18:44
  • Triple backslash doesn't work for me either. But I think that the core issue here is that I should not use the public String[] split(String regExp) method when reading and processing a file, as the behavior may be unpredictable.
    – Andrew
    Commented Feb 17, 2016 at 9:17
  • But is there any other way?
    – Andrew
    Commented Feb 17, 2016 at 9:53
1

Note if the string object is too large you will get the exception Regex too complicated. Your regex is actually fine, but you need to truncate the string. In this case you can do something like the following:

Blob blobValue = (Blob)record.get(blobField);
// Truncate string then split on newline, limiting to 11 entries
List<String> preview = blobValue.toString().substring(0,1000).split('\n', 11);
// Remove the last entry, because The list’s last entry contains all input beyond the last matched delimiter.
preview.remove(preview.size()-1);
// In my use-case, I needed to return a string, and String.join() works as the reverse of split()    
return String.join(preview, '\n');
1

I have found

List<String> lstRows = strVariable.split('\n|\r\n');

works the best for me - as it handles either single newline or nl/cr text.

Additionally, if you don't care about indentation and want just the values on each line:

List<String> lstRows = strVariable.split('\n');
for ( String row : lstRows ) {
    row = row.trim();
    
    ...do stuff with row...

}

lstRows will have the carriage return on it which you then trim off using .trim()

0

You should only need to supply '\n' as the regular expression. The backslash is interpreted within the String as starting an escape sequence resulting in a single code point (will just call this a character). Since the split method takes a string as the regular expression, this single character will be taken as the delimiter for the split. AFAIK the {newline} character has no significance in the Apex version of regular expressions so no need to escape it like '\(' or '\['.

BTW processing complex CSVs can get extremely difficult (maybe impossible) using regular expressions. A "cell" can contain {newline} characters as long as the cell value is surrounded by double quotes, and in fact it can contain escaped double quotes making this a very messy topic. As of February 2021 I found the String "escapeCsv" method to encode a cell, but no corresponding "unescapeCsv" for either a cell or more importantly a file. Also Windows often uses '\r\n' rather than just '\n', while some old Mac programs would use only '\r'.

You must log in to answer this question.

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