使用javascript / regex对网页上的行进行排序

时间:2009-10-11 18:27:08

标签: javascript regex sorting greasemonkey

我想编写一个Greasemonkey脚本,需要查找以字符串结尾的行(“副本”)&根据该字符串前面的数字对这些行进行排序。

我想要修改的页面不会使用表格,只是br / tag,所以我认为这将涉及正则表达式:

http://www.publishersweekly.com/article/CA6591208.html

(没有匹配字符串的行将被忽略。)

感谢任何让我入门的提示。

3 个答案:

答案 0 :(得分:2)

大多数情况下,HTML和RegEx不会在一起,在解析HTML时,您首先想到的不应该是RegEx。

然而,在这种情况下,标记看起来很简单,应该没问题 - 至少在发布者周刊改变他们执行该页面的方式之前。

这是一个函数,它将提取数据,获取相应的行,对它们进行排序,然后再将它们放回原位:
($ j是jQuery)

function reorderPwList()
{
    var Container = $j('#article span.table');

    var TargetLines = /^.+?(\d+(?:,\d{3})*) copies\.<br ?\/?>$/gmi

    var Lines = Container.html().match( TargetLines );

    Lines.sort( sortPwCopies );

    Container.html( Lines.join('\n') );


    function sortPwCopies()
    {
        function getCopyNum()
        { return arguments[0].replace(TargetLines,'$1').replace(/\D/g,'') }

        return getCopyNum(arguments[0]) - getCopyNum(arguments[1]);
    }
}


对那里使用的正则表达式的解释:

^           # start of line
.+?         # lazy match one or more non-newline characters
(           # start capture group $1
  \d+       # match one or more digits (0-9)
  (?:       # non-capture group
    ,\d{3}  # comma, then three digits
  )*        # end group, repeat zero or more times
)           # end group $1
 copies\.   # literal text, with . escaped
<br ?\/?>   # match a br tag, with optional space or slash just in case
$           # end of line

(为了便于阅读,我缩进了组 - 只有'副本'之前的空格和'br'之后的空格才有效。)
使用正则表达式标志gmi g lobal, m 多线模式,case- i nsensitive matching。



&lt; OLD ANSWER&gt;

一旦你只提取了你想要查看的文本(使用DOM / jQuery),你就可以将它传递给下面的函数,这将把相关信息放入一个可以进行排序的格式:

function makeSortable(Text)
{
    // Mark sortable lines and put number before main content.
    Text = Text.replace
        ( /^(.*)([\d,]+) copies\.<br \/>/gm
        , "SORT ME$2    $1"
        );

    // Remove anything not marked for sorting.
    Text = Text.replace( /^(?!SORT ME).*$/gm , '' );

    // Remove blank lines.
    Text = Text.replace( /\n{2,}/g , '\n' );

    // Remove sort token.
    Text = Text.replace( /SORT ME/g , '' );

    return Text;
}


然后,您需要一个sort函数来确保数字正确排序(标准的JS array.sort方法将对文本进行排序,并在20,000之前放置100,000个。)


哦,这里有一个关于这里使用的正则表达式的快速解释:

/^(.*)([\d,]+) copies\.<br \/>/gm

/.../gm    a regex with global-match and multi-line modes
^          matches start of line
(.*)       capture to $1, any char (except newline), zero or more times
([\d,]+)   capture to $2, any digit or comma, one or more times
 copies    literal text
\.<br \/>  literal text, with . and / escaped (they would be special otherwise)


/^(?!SORT ME).*$/gm

/.../gm      again, enable global and multi-line
^            match start of line
(?!SORT ME)  a negative lookahead, fails the match if text 'SORT ME' is after it
.*           any char (except newline), zero or more times
$            end of line


/\n{2,}/g

\n{2,}    a newline character, two or more times

&lt; / OLD ANSWER&gt;

答案 1 :(得分:1)

你可以从这样的事情开始(只需将copypaste插入firebug控制台)

    // where are the things
    var elem = document.getElementById("article").
        getElementsByTagName("span")[1].
        getElementsByTagName("span")[0];

    // extract lines into array
    var lines = []
    elem.innerHTML.replace(/.+?\d+\s+copies\.\s*<br>/g,
       function($0) { lines.push($0) });

    // sort an array

//      lines.sort(function(a, b) {
//         var ma = a.match(/(\d+),(\d+)\s+copies/);
//         var mb = b.match(/(\d+),(\d+)\s+copies/);
//
//         return parseInt(ma[1] + ma[2]) - 
//              parseInt(mb[1] + mb[2]);

            lines.sort(function(a, b) {
                 function getNum(p) {
                     return parseInt(
                          p.match(/([\d,]+)\s+copies/)[1].replace(/,/g, ""));
                 }
                 return getNum(a) - getNum(b);
    })

    // put it back
    elem.innerHTML = lines.join("");

答案 2 :(得分:0)

我不清楚你要做的是什么。在此处发布问题时,我建议您发布(部分)实际数据,并清楚地指出您想要匹配的内容。

但是,我猜你知道很少有正则表达式,在这种情况下,为什么要使用正则表达式呢?如果你稍微研究一下这个话题,你很快就会知道正则表达式不是一个产生你想到的任何东西的神奇工具。正则表达式不能以任何方式排序。它只是匹配文本,这就是全部。

看看这个出色的在线资源:http://www.regular-expressions.info/

如果在阅读之后你认为你的问题的正则表达式解决方案是合适的,请随时详细说明你的问题,我确信我或其他人能够帮助你。

祝你好运。