Véase Comma Separated Values en la Wikipedia:
A comma-separated values (CSV) file stores tabular data (numbers and text) in plain-text form. A CSV file consists of any number of records, separated by line breaks of some kind; each record consists of fields, separated by a comma. All records have an identical sequence of fields.
split por las comas:
> x = '"earth",1,"moon",9.374' '"earth",1,"moon",9.374' > y = x.split(/,/) [ '"earth"', '1', '"moon"', '9.374' ]
Esta solución deja las comillas dobles en los campos entrecomillados.
Peor aún, los campos entrecomillados pueden contener comas, en cuyo
caso la división proporcionada por split sería errónea:
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > y = x.split(/,/) [ '"earth', ' mars"', '1', '"moon', ' fobos"', '9.374' ]
La siguiente expresión regular reconoce cadenas de comillas dobles con secuencias de escape seguidas opcionalmente de una coma:
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > r = /"((?:[^"\\]|\\.)*)"\s*,?/g /"((?:[^"\\]|\\.)*)"\s*,?/g > w = x.match(r) [ '"earth, mars",', '"moon, fobos",' ]
Esta otra expresión regular /([^,]+),?|\s*,/ actúa de forma parecida al split.
Reconoce secuencias no vacías de caracteres que no contienen comas seguidas opcionalmente
de una coma o bien una sóla coma (precedida opcionalmente de blancos):
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > r = /([^,]+),?|\s*,/g /([^,]+),?|\s*,/g > w = x.match(r) [ '"earth,', ' mars",', '1,', '"moon,', ' fobos",', '9.374' ]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>CSV Analyzer</title>
<link href="global.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="../../underscore/underscore.js"></script>
<script type="text/javascript" src="../../jquery/starterkit/jquery.js"></script>
<script type="text/javascript" src="csv.js"></script>
</head>
<body>
<h1>Comma Separated Value Analyzer</h1>
<div>
<i>Write a CSV string. Click the table button. The program outputs a table with the specified data.</i>
</div>
<table>
<tr>
<th>CSV string:</th> <!-- autofocus attribute is HTML5 -->
<td><textarea autofocus cols = "80" rows = "5" id="original"></textarea></td>
</tr>
</table>
<button type="button">table:</button><br>
<span class="output" id="finaltable"></span>
</body>
</html>
html *
{
font-size: large;
/* The !important ensures that nothing can override what you've set in this style (unless it is also important). */
font-family: Arial;
}
h1 { text-align: center; font-size: x-large; }
th, td { vertical-align: top; text-align: right; }
/* #finaltable * { color: white; background-color: black; } */
/* #finaltable table { border-collapse:collapse; } */
/* #finaltable table, td { border:1px solid white; } */
#finaltable:hover td { background-color: blue; }
tr:nth-child(odd) { background-color:#eee; }
tr:nth-child(even) { background-color:#00FF66; }
input { text-align: right; border: none; } /* Align input to the right */
textarea { border: outset; border-color: white; }
table { border: inset; border-color: white; }
table.center { margin-left:auto; margin-right:auto; }
#result { border-color: red; }
tr.error { background-color: red; }
body
{
background-color:#b0c4de; /* blue */
}
// See http://en.wikipedia.org/wiki/Comma-separated_values "use strict"; // Use ECMAScript 5 strict mode in browsers that support it $(document).ready(function() { $("button").click(function() { calculate(); }); }); function calculate() { var result; var original = document.getElementById("original"); var temp = original.value; var regexp = /_____________________________________________/g; var lines = temp.split(/\n+\s*/); var commonLength = NaN; var r = []; // Template using underscore var row = "<%% _.each(items, function(name) { %>" + " <td><%%= name %></td>" + " <%% }); %>"; if (window.localStorage) localStorage.original = temp; for(var t in lines) { var temp = lines[t]; var m = temp.match(regexp); var result = []; var error = false; if (m) { if (commonLength && (commonLength != m.length)) { //alert('ERROR! row <'+temp+'> has '+m.length+' items!'); error = true; } else { commonLength = m.length; error = false; } for(var i in m) { var removecomma = m[i].replace(/,\s*$/,''); var remove1stquote = removecomma.replace(/^\s*"/,''); var removelastquote = remove1stquote.replace(/"\s*$/,''); var removeescapedquotes = removelastquote.replace(/\"/,'"'); result.push(removeescapedquotes); } var tr = error? '<tr class="error">' : '<tr>'; r.push(tr+_.template(row, {items : result})+"</tr>"); } else { alert('ERROR! row '+temp+' does not look as legal CSV'); error = true; } } r.unshift('<p>\n<table class="center" id="result">'); r.push('</table>'); //alert(r.join('\n')); // debug finaltable.innerHTML = r.join('\n'); } window.onload = function() { // If the browser supports localStorage and we have some stored data if (window.localStorage && localStorage.original) { document.getElementById("original").value = localStorage.original; } };
Casiano Rodríguez León