拉取网页上的价格以及每种价格的字体大小

时间:2013-01-12 03:55:34

标签: jquery regex

我正在jquery中创建一个bookmarklet,它应该能够在页面上找到价格并拉出每个价格被替换的字体大小。我最大的困难是找到一种使用方法:包含正则表达式。看来:contains只能与精确文本一起使用。 这就是我的开始。基本上我想按价格去价格并获得它的字体大小。

jQuery(":contains('" + jQuery('body').text().match(/[$€£]\d{1,3}(,?\d{3})?(\.\d{2})?/g)+ "')").each( function() { 
var size = parseInt( jQuery(this).css( 'fontSize' ), 10 ); 
results.push({ size: size, price: price}); 
});

2 个答案:

答案 0 :(得分:1)

我怀疑您可以先搜索货币符号,然后使用正则表达式$.grep()$.filter()来获得结果。让我把一个jsFiddle放到一起演示(我不是每个bookmarklet,所以我不确定如何从一个内部引用jQuery)。

编辑2

以下尝试获取最内层元素$.text()并忽略父元素。同样,我怀疑该方法不能完美地处理具有多个内部元素的段落标记,两者都具有价格字符串。但它比以下更进一步。

你会在小提琴中看到一些更冗长的东西,但以下是让它起作用的部分。

function containsSelector(value) {
  return ':contains(' + value + ')';
}

function groupContainsSelector(list) {
  return $.map(list, containsSelector).join(',');
}

function groupExpression(list) {
  var expression = '[' + list.join('') + ']\\d{1,3}(,?\\d{3})?(\\.\\d{2})?';

  if (!expressions.hasOwnProperty(expression)) {
    expressions[expression] = new RegExp(expression, 'g');
  }

  return expressions[expression];
}

请注意,我缓存了RegExp,所以我不是要求我已经创建的新的。

function hasCurrency($el, currency, test) {
  if ($el.children(currency).size()) {
    return false;
  }

  return !!$el.text().match(test);
}

使用这些功能,我们可以根据具体情况使用以下其中一种:

$contains = $(currencieselector, document.body);

$filter = $contains.filter(function (i, el) {
  return hasCurrency($(el), currencieselector, groupexp);
});

$grep = $.grep($contains, function (el, i) {
  return hasCurrency($(el), currencieselector, groupexp);
});

$map = $contains.map(function () {
  return !hasCurrency($(this), currencieselector, groupexp) || this;
});

http://jsfiddle.net/userdude/CvYpx/9/

我使用setTimeout来应用应用于每个方法中找到的元素的每个样式层。除了$contains之外,其他三个是相同的结果。我还要强调每个面额:

$.each(currencies, function (index, val) {
  $contains.filter(function (i, el) {
    return hasCurrency($(el), containsSelector(val), groupExpression([val]));
  })
  .addClass(denominations[index]);
});

修改

这或多或少是我所得到的,有一些人为的例子:

<p>Franc: £58,00</p>
<aside>No price</aside>
<p>Dollar: $8.08</p>
<p>Euro: €5.34</p>
<p>No price</p>
<p>SPAN price: <span>€3,00</span></p>
<p>STRONG: <strong>£73.93</strong></p>
<p>EM: <em>$73.93</em></p>

var $contains = $(':contains($),:contains(€),:contains(£)', document.body),
    regex = /[$€£]\d{1,3}(,?\d{3})?(\.\d{2})?/g,
    $filter,
    $grep;

$grep = $.grep($contains, function(n, i){
    console.log($(n).text().match(regex), $(n).text());
    return !!$(n).text().match(regex);
});

$filter = $contains.filter(function(n, i){
    console.log($(i).text().match(regex));
    return !!$(i).text().match(regex);
});

console.log($contains);
console.log($filter);
console.log($grep);

http://jsfiddle.net/userdude/CvYpx/

注意,在结果中找到parentchild的问题,我不确定您是否想要这样做。另外,正则表达式我不擅长,所以没有评论。所以它并不完美,但它是$.grep()$.filter()的总体思路。

答案 1 :(得分:0)

您可能需要考虑不同的方法:获取页面上的所有文本节点,并且对于与正则表达式匹配的每个节点,获取父节点的计算样式的字体大小。这可能看起来效率低下,但实际上并非如此:jQuery已经必须做类似的事情来评估您的contains查询。