PHP's str_getcsv in TypeScript

✓ Verified: PHP 8.3
Examples tested against actual runtime. CI re-verifies continuously. Only documented examples are tested.

How to use

Install via yarn add locutus and import: import { str_getcsv } from 'locutus/php/strings/str_getcsv'.

Or with CommonJS: const { str_getcsv } = require('locutus/php/strings/str_getcsv')

Use a bundler that supports tree-shaking so you only ship the functions you actually use. Vite, webpack, Rollup, and Parcel all handle this. For server-side use this is less of a concern.

Examples

These examples are extracted from test cases that automatically verify our functions against their native counterparts.

#codeexpected result
1str_getcsv('"abc","def","ghi"')['abc', 'def', 'ghi']
2str_getcsv('"row2""cell1","row2cell2","row2cell3"', null, null, '"')['row2"cell1', 'row2cell2', 'row2cell3']

Here's what our current TypeScript equivalent to PHP's str_getcsv looks like.

export function str_getcsv(
input: string,
delimiter?: string | null,
enclosure?: string | null,
escapeCharacter?: string | null,
): string[] {
// discuss at: https://locutus.io/php/str_getcsv/
// parity verified: PHP 8.3
// original by: Brett Zamir (https://brett-zamir.me)
// example 1: str_getcsv('"abc","def","ghi"')
// returns 1: ['abc', 'def', 'ghi']
// example 2: str_getcsv('"row2""cell1","row2cell2","row2cell3"', null, null, '"')
// returns 2: ['row2"cell1', 'row2cell2', 'row2cell3']

/*
// These test cases allowing for missing delimiters are not currently supported
str_getcsv('"row2""cell1",row2cell2,row2cell3', null, null, '"');
['row2"cell1', 'row2cell2', 'row2cell3']

str_getcsv('row1cell1,"row1,cell2",row1cell3', null, null, '"');
['row1cell1', 'row1,cell2', 'row1cell3']

str_getcsv('"row2""cell1",row2cell2,"row2""""cell3"');
['row2"cell1', 'row2cell2', 'row2""cell3']

str_getcsv('row1cell1,"row1,cell2","row1"",""cell3"', null, null, '"');
['row1cell1', 'row1,cell2', 'row1","cell3'];

Should also test newlines within
*/

let i = 0
let inpLen = 0
const output: string[] = []
const _backwards = function (str: string): string {
// We need to go backwards to simulate negative look-behind (don't split on
// an escaped enclosure even if followed by the delimiter and another enclosure mark)
return str.split('').reverse().join('')
}
const _pq = function (str: string): string {
// preg_quote()
return String(str).replace(/([\\.+*?[^\]$(){}=!<>|:])/g, '\\$1')
}

const delimiterValue = delimiter || ','
const enclosureValue = enclosure || '"'
const escapeValue = escapeCharacter || '\\'
const pqEnc = _pq(enclosureValue)
const pqEsc = _pq(escapeValue)

const trimmedInput = input.replace(new RegExp('^\\s*' + pqEnc), '').replace(new RegExp(pqEnc + '\\s*$'), '')

// PHP behavior may differ by including whitespace even outside of the enclosure
const entries = _backwards(trimmedInput)
.split(new RegExp(pqEnc + '\\s*' + _pq(delimiterValue) + '\\s*' + pqEnc + '(?!' + pqEsc + ')', 'g'))
.reverse()

for (i = 0, inpLen = entries.length; i < inpLen; i++) {
output.push(_backwards(entries[i] ?? '').replace(new RegExp(pqEsc + pqEnc, 'g'), enclosureValue))
}

return output
}

Improve this function

Locutus is a community effort following The McDonald's Theory: we ship first iterations, hoping others will improve them. If you see something that could be better, we'd love your contribution.

View on GitHub · Edit on GitHub · View Raw


« More PHP strings functions


Star