<commit_before>var ATTR_RE = RegExp(
    '\\[([^=~|\\]]+)\\s*(?:([\\|~]=|=)\\s*'
    + '("(?:[^"]|\\")+"|'
    + "(?:'(?:[^']|\\')+')|[\\w-]+))?\\]"
);

module.exports = function (selector) {
    return split(selector).map(function (s) {
        if (s === '>' || s === '+') return s;
        
        var m = {
            name: s.match(/^([\w-]+|\*)/),
            'class': s.match(/\.[\w-]+/g),
            id: s.match(/#([\w-]+)/),
            pseudo: s.match(/:([\w-]+)/),
            attribute: s.match(ATTR_RE)
        };
        var classes = (m['class'] || []).map(function (c) {
            return c.replace(/^\./, '');
        });
        
        var res = {
            name: m.name && m.name[1].toUpperCase(),
            'class': classes,
            id: m.id && m.id[1],
            pseudo: m.pseudo && m.pseudo[1],
            attribute: {}
        };
        
        if (!m.attribute) return res;
        
        var name = m.attribute[1];
        var op = m.attribute[2];
        if (!op) {
            res.attribute.exists = name;
            return res;
        }
        var key = {
            '=': 'equals',
            '~=': 'contains',
            '|=': 'begins'
        }[op];
        
        var value = m.attribute[3];
        if (/^"/.test(value)) {
            value = value.replace(/^"|"$/g).replace(/\\"/g, '"');
        }
        else if (/^'/.test(value)) {
            value = value.replace(/^'|'$/g).replace(/\\'/g, "'");
        }
        res.attribute[key] = [ name, value ];
        
        return res;
    }).filter(Boolean);
};

function split (s) {
    var res = [];
    var escaped = false;
    var quoted = false;
    var expr = false;<commit_msg>fix bug in quoted values<commit_after>var ATTR_RE = RegExp(
    '\\[([^=~|\\]]+)\\s*(?:([\\|~]=|=)\\s*'
    + '("(?:[^"]|\\")+"|'
    + "(?:'(?:[^']|\\')+')|[\\w-]+))?\\]"
);

module.exports = function (selector) {
    return split(selector).map(function (s) {
        if (s === '>' || s === '+') return s;
        
        var m = {
            name: s.match(/^([\w-]+|\*)/),
            'class': s.match(/\.[\w-]+/g),
            id: s.match(/#([\w-]+)/),
            pseudo: s.match(/:([\w-]+)/),
            attribute: s.match(ATTR_RE)
        };
        var classes = (m['class'] || []).map(function (c) {
            return c.replace(/^\./, '');
        });
        
        var res = {
            name: m.name && m.name[1].toUpperCase(),
            'class': classes,
            id: m.id && m.id[1],
            pseudo: m.pseudo && m.pseudo[1],
            attribute: {}
        };
        
        if (!m.attribute) return res;
        
        var name = m.attribute[1];
        var op = m.attribute[2];
        if (!op) {
            res.attribute.exists = name;
            return res;
        }
        var key = {
            '=': 'equals',
            '~=': 'contains',
            '|=': 'begins'
        }[op];
        
        var value = m.attribute[3];
        if (/^"/.test(value)) {
            value = value.replace(/^"|"$/g, '').replace(/\\"/g, '"');
        }
        else if (/^'/.test(value)) {
            value = value.replace(/^'|'$/g, '').replace(/\\'/g, "'");
        }
        res.attribute[key] = [ name, value ];
        
        return res;
    }).filter(Boolean);
};

function split (s) {
    var res = [];
    var escaped = false;
    var quoted = false;
    var expr = false;
{'fraction_non_alphanumeric': 0.2522733939571722, 'fraction_numerical': 0.0035200938691698444, 'mean_word_length': 1.3468685478320717, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4284434', 'n_tokens_mistral': 1187, 'n_tokens_neox': 1149, 'n_words': 211}