Как разобрать сложную строку с помощью плагина jQuery Tablesorter?

У меня есть такая таблица, которую я хочу отсортировать:
| Имя | Дело |
| Джон | Х-123/08 П|
| Боб | Х-123/09 |
| Дилан | Х-45/10 |

Я хочу отсортировать столбец дела по году дела, а затем по номеру дела, зная, что формат всегда «X- (от 1 до 4 цифр для номера дела)/(год дела на 2 цифрах) (иногда некоторый текст)». Возможно, после случая года у меня есть какой-то текст, но его следует игнорировать при сортировке.

Я использую плагин tablesorter jQuery, и я изо всех сил пытаюсь добавить для этого собственный синтаксический анализатор.

Спасибо за вашу помощь !

РЕДАКТИРОВАТЬ: Вот что я пытаюсь сделать:

jQuery.tablesorter.addParser({ 
                // set a unique id 
                id: 'case', 
                is: function(s) { 
                    return false; 
                }, 
                format: function(s) { 
                    // format your data for normalization 
                    return s.replace(/^X-\d{1,4}\/(\d{2}).*$/, '$1') + ('000' + s.replace(/^X-(\d{1,4})\/\d{2}.*$/, '$1')).substr(-4);
                }, 
                // set type, either numeric or text 
                type: 'text'
            }); 

Он отлично работает, пока я не сталкиваюсь с случаем с 2 цифрами, который затем оценивается выше, чем с 3 цифрами, и я не понимаю, почему ... "X-458/09 P" сортируется меньше, чем "X-48/09" . Я попробую отладить, чтобы увидеть, что на самом деле происходит.

РЕДАКТИРОВАТЬ 2: Также попробовал второй ответ:

jQuery.tablesorter.addParser({ 
                // set a unique id 
                id: 'case', 
                is: function(s) { 
                    return false; 
                }, 
                format: function(s) { 
                    var m = s.match(/X\-(\d+)\/(\d{2}).*$/);
                    var affaire = m[1];
                    var year = m[2];
                    return year + '000' + affaire;
                }, 
                // set type, either numeric or text 
                type: 'text'
            }); 

Результат, кажется, такой же, как и первый... Я действительно не могу понять, почему это отстой. Почему tablesorter считает, что 488 000 10 меньше, чем 49 000 10 ?!


person Anth0    schedule 27.12.2010    source источник


Ответы (3)


Я думаю, вы можете использовать:

$.tablesorter.addParser({ 
    // set a unique id 
    id: 'case', 
    is: function(s) { 
        // return false so this parser is not auto detected 
        return false; 
    }, 
    format: function(s) { 
        // format your data for normalization 
        return s.replace(/^X-\d{1,4}\/(\d{2}).*$/, '$1') + ('000' + s.replace(/^X-(\d{1,4})\/\d{2}.*$/, '$1')).slice(-4);
    }, 
    // set type, either numeric or text 
    type: 'text'
}); 

РЕДАКТИРОВАТЬ:

Возможно, вы уже пробовали что-то подобное с type: 'numeric'; Я не уверен, но это может не сработать, потому что parseInt('09') === 0.

РЕДАКТИРОВАТЬ 2:

Изменено, чтобы отразить сортировку по году, а затем по номеру дела.

person Spiny Norman    schedule 27.12.2010
comment
Я уже пробовал это, но, похоже, это не работает =( Я пробовал и числовое, и текстовое. Я добавил что-то в описание вопроса, может быть, это причина.. - person Anth0; 27.12.2010
comment
Иногда какой-то текст, а? :) Попробуйте добавить .* перед $ в конце? Это вообще работает? - person Spiny Norman; 27.12.2010
comment
Да, такой текст: X-123/07 PRU или X-54/11 P(C). Обычно это всего несколько букв, и их не следует учитывать при сортировке. Я пробовал с .*, но все равно без шансов. - person Anth0; 27.12.2010
comment
Хорошо, просто чтобы убедиться: вы добавили $("table").tablesorter({ headers: { 1: { sorter:'case' } } }); или что-то в этом роде, верно? Поскольку X-54/11 P(C).replace(/^X-\d{1,4}\/(\d{2}).*$/, '$1') возвращает 11 в моей консоли... Вы уверены, что функция формата вызывается? Может быть, добавить туда отладочный код или просто alert(s); alert(s.replace(/^X-\d{1,4}\/(\d{2}).*$/, '$1'));? - person Spiny Norman; 27.12.2010
comment
Парсер вызывается, я уже сделал отладку, чтобы проверить это. Год действительно хорошо возвращается, когда я пробую предупреждение (...), но я хочу сортировать по году, а затем по номеру дела (внутри года) =/ - person Anth0; 27.12.2010
comment
Ах хорошо. Я этого не понял... Я изменил регулярное выражение, включив в него номер дела. Однако в этом случае 54 будет больше, чем 123, поэтому, если вы хотите исключить и это, вам придется использовать более одного регулярного выражения (я думаю). Я включил пример в комментарий ниже (заполнение нулями). РЕДАКТИРОВАТЬ: или используйте .match() вместо .replace(), чтобы получить регистр и год, как это сделал @Nick Craver, а затем добавьте их вместе с нулями между ними. - person Spiny Norman; 27.12.2010
comment
Мы почти у цели, но не совсем. Я не очень понимаю ваше прокомментированное выражение, и это то, что мне нужно использовать, потому что я не хочу, чтобы 54 было больше 123. Я попробовал это, и он довольно хорошо сортирует мой список, за исключением случаев с двумя цифрами, которые больше более 3 цифр (например, X-228/10 меньше, чем X-25/10). Не могли бы вы уточнить, что вы пытаетесь сделать? - person Anth0; 27.12.2010
comment
Ну, я хочу, чтобы строка состояла из последних 4 символов «000» + номер дела. Таким образом (я думаю) это должно быть упорядочено в правильном, гм, порядке. Кроме того, я уверен, что это должно сработать. Можете ли вы показать мне часть вашего кода? Я также обновлю ответ. - person Spiny Norman; 27.12.2010
comment
Я голосую за ваш ответ, потому что он очень помог мне получить успешный ответ! Спасибо :) - person Anth0; 27.12.2010
comment
Хм... как насчет того, чтобы использовать slice вместо substr? (а также, спасибо :), но я все равно хотел бы, чтобы это был лучший ответ;)) - person Spiny Norman; 27.12.2010

Вы можете использовать регулярное выражение, чтобы получить 2 значения, которые вам нужны, например:

var columnVal = "X-123/08";
var m = columnVal.match(/X\-(\d+)\/(\d{2})$/);
var case = m[1];
var year = m[2];
person Nick Craver    schedule 27.12.2010

После того, как вы попробовали несколько вещей, это, кажется, работает отлично:

jQuery.tablesorter.addParser({ 
                // set a unique id 
                id: 'case', 
                is: function(s) { 
                    return false; 
                }, 
                format: function(s) { 
                    var m = s.match(/X\-(\d+)\/(\d{2}).*$/);
                    var caseVar = '000' + m[1];
                    var size = caseVar.length;
                    caseVar= caseVar.substr(size-4, 4);
                    var year = m[2];
                    return jQuery.tablesorter.formatFloat(year + caseVar);
                }, 
                // set type, either numeric or text 
                type: 'numeric'
            }); 

Я провел некоторое исследование, и оказалось, что функция substr с отрицательным значением не работает во всех браузерах (я использую IE, потому что мое приложение должно быть совместимо с IE). Я думаю, что это причина моих предыдущих проблем, и поэтому решение Spiny не сработало для меня.

В любом случае спасибо всем вам за вашу драгоценную помощь!

person Anth0    schedule 27.12.2010