配列からテーブルを作る
<!DOCTYPE html>
<meta charset="utf-8">
<title></title>
<style>
.red { color: red;}
</style>
<body>
<table border="1" id="TB"></table>
<script>
function ary2thead (ary = [ ], thead = document.createElement ('thead')) {
const
textSplitStr = (
th = '(#)?',
rowSpan = '(?:r([2-9]|[1-9][0-9]+)|r[01]|r0[0-9]+)?',
colSpan = '(?:c([2-9]|[1-9][0-9]+)|c[01]|c0[0-9]+)?',
attr = '(?:\\{(.+)?\\})?',
text = '\\s*(.*)\\s*',
ctrlCom = '(?:!(?=[rc\\{])'+ rowSpan + colSpan + attr + ')?'
)=> '^' + th + ctrlCom + text + '$',
attrSplitStr = '\\s*(.+?)\\s*\\:\\s*(.*?)\\s*(?:,|;|$)',
rows = [ ];
for (let row of ary) {
let tds = [];
for (let cell of row) {
let
splitter = new RegExp (textSplitStr (), 'gi');
[, th, rowSpan, colSpan, attr, textContent = ''] = splitter.exec (cell) ?? [ ],
prop = new Map;
if (rowSpan)
prop.set ('rowSpan', rowSpan);
if (colSpan)
prop.set ('colSpan', colSpan);
if (attr)
for (let a, splitter = new RegExp (attrSplitStr, 'gi'); a = splitter.exec (attr); )
prop.set (a[1],a[2]);
prop.set ('textContent', textContent);
tds.push (Object.assign (document.createElement (th ? 'th': 'td'), Object.fromEntries (prop)));
}
rows.push (tds);
}
rows.reduce ((a, b)=>(a.insertRow ().append (...b), a), thead);
return thead;
}
const RECS = `
#!R2C1 No #!r2 Name #!r1c2 INFO
#Age #ETC
#1 akio 57 abc
#!{id:sss,className: red}2 ayako 56 def
`;
const csv2ary = csv => csv.split (/r\n|\r|\n/g).reduce ((a,b)=>b.trim()?[...a,b]:a,[]).map (row=> row.split (/\t/g));
ary2thead (csv2ary (RECS), TB);
</script>
ショートコーディングしてみる
<!DOCTYPE html>
<meta charset="utf-8">
<title></title>
<style>
.red { color: red;}
</style>
<body>
<table border="1" id="TB"></table>
<script>
function ary2tbody (recs = [ ], tbody = document.createElement ('tbody')) {
function* splitter(a,b=new RegExp(attrSplitStr,'g'),c){while(c=b.exec(a))yield c.slice(1)}
const
addObj = (a,[b,c])=>(a[b]=c,a),
delObj = (a,[b,c])=>((undefined===c)&&delete a[b],a),
makeTD = (a)=>{
let
[, th, rowSpan, colSpan, attr, textContent] = (new RegExp (textSplitStr, 'i')).exec (a) ?? [ ],
prop = [...splitter (attr)].reduce (addObj, { rowSpan, colSpan, textContent });
return Object.assign (
document.createElement (th ? 'th': 'td'),
Object.entries (prop).reduce (delObj, prop)
)
},
attrSplitStr = '\\s*(.+?)\\s*\\:\\s*(.*?)\\s*(?:,|;|$)',
textSplitStr =
'^' + '(#)?' +
'(?:!(?=[rc{])'+
'(?:r([2-9]|[1-9][0-9]+)|r[01]|r0[0-9]+)?' +
'(?:c([2-9]|[1-9][0-9]+)|c[01]|c0[0-9]+)?' +
'(?:\\{(.+)?\\})?' +
')?' +
'\\s*(.*)\\s*' + '$';
recs.forEach (row=> tbody.insertRow ().append (...row.map (makeTD)));
return tbody;
}
const RECS = `
#!R2C1 No #!r2 Name #!r1c2 INFO
#Age #ETC
#1 akio 57 abc
#!{id:sss,className: red}2 ayako 56 def
`;
const csv2ary = csv => csv.split (/r\n|\r|\n/g).reduce ((a,b)=>b.trim()?[...a,b]:a,[]).map (row=> row.split (/\t/g));
ary2thead (csv2ary (RECS), TB);
</script>
さらにショート!
<!DOCTYPE html>
<meta charset="utf-8">
<title></title>
<style>
.red { color: red;}
</style>
<body>
<table border="1" id="TB"></table>
<script>
const ary2tbody=(a=[],b=document.createElement('tbody'))=>{
function*c(a,b=new RegExp('\\s*(.+?)\\s*\\:\\s*(.*?)\\s*(?:,|;|$)','g'),c){while(c=b.exec(a))yield c.slice(1)}
const d=(a,[b,c])=>(a[b]=c,a),e=(a,[b,c])=>((undefined===c)&&delete a[b],a),f=g=>{let[,h,i,j,k,l]=(new RegExp('^(#)?(?:!(?=[rc{])(?:r([2-9]|[1-9][0-9]+)|r[01]|r0[0-9]+)?(?:c([2-9]|[1-9][0-9]+)|c[01]|c0[0-9]+)?(?:\\{(.+)?\\})?)?\\s*(.*)\\s*$','i')).exec(g)??[],m=[...c(k)].reduce(d,{rowSpan:i,colSpan:j,textContent:l});return Object.assign(document.createElement(h?'th':'td'),Object.entries(m).reduce(e,m))};
a.forEach(c=>b.insertRow().append(...c.map(f)));return b}
const RECS = `
#!R2C1 No #!r2 Name #!r1c2 INFO
#Age #ETC
#1 akio 57 abc
#!{id:sss,className: red}2 ayako 56 def
`;
const csv2ary = csv => csv.split (/r\n|\r|\n/g).reduce ((a,b)=>b.trim()?[...a,b]:a,[]).map (row=> row.split (/\t/g));
ary2tbody (csv2ary (RECS), TB);
</script>
再考して更に短く
const
ary2tbody=(a=[],b=document.createElement('tbody'))=>{
let A='^(#)?(?:!(?=[rc\\{])(?:r([2-9]|[1-9]\\d+)|r[01]|r0\\d+)?(?:c([2-9]|[1-9]\\d+)|c[01]|c0\\d+)?(?:\\{(.+)?\\})?)?\\s*(.*)\\s*$',B=RegExp,C=Object;
a.map(c=>{b.insertRow().append(...c.map(d=>{let[,z,y,x,w,v]=(new B(A,'i')).exec(d)??[],u={rowSpan:y,colSpan:x,textContent:v};
C.entries(u).map(a=>a[1]===undefined&&delete u[a[0]]);for(let a,b=new B('\\s*(.+?)\\s*\\:\\s*(.*?)\\s*(,|;|$)','g');a=b.exec(w);u[a[1]]=a[2]);
return C.assign(document.createElement(z?'th':'td'),u)}))});return b};