如何获取页面上使用的所有单词的数组

时间:2013-06-03 21:51:32

标签: javascript jquery

所以我正在尝试获取我的网页中使用的所有单词的数组。

应该很容易,对吧?

我遇到的问题是$("body").text().split(" ")返回一个数组,其中一个元素开头的单词和另一个元素的结尾的单词连接成一个。

即:

<div id="1">Hello
    <div id="2">World</div>
</div>
当我希望它返回["HelloWorld"]时,

返回["Hello", "World"]

我也尝试过:

wordArr = [];

function getText(target)
{    
    if($(this).children())
    {
        $(this).children(function(){getText(this)});
    }
    else
    {
        var testArr = $(this).text().split(" ");
        for(var i =0; i < testArr.length; i++)
            wordArr.push(testArr[i]);
    }

}

getText("body");

但是$(node).children()对于存在的DOM中的任何节点都是真实的,因此无效。

我确定我错过了一些明显的东西,所以我会欣赏一双额外的眼睛。

对于它的价值,我不需要唯一的单词,只需要文档正文中的每个单词作为数组中的元素。我正在尝试使用它来生成上下文和词汇共现与另一组单词,因此重复一个给定单词的上下文重要性。

提前感谢任何想法。

请参阅Fiddle

4 个答案:

答案 0 :(得分:6)

这样的事情怎么样?

 var res = $('body  *').contents().map(function () {
    if (this.nodeType == 3 && this.nodeValue.trim() != "") 
        return this.nodeValue.trim();
}).get().join(" ");
console.log(res);

Demo

获取一系列单词:

var res = $('body  *').contents().map(function () {
    if (this.nodeType == 3 && this.nodeValue.trim() != "") //check for nodetype text and ignore empty text nodes
        return this.nodeValue.trim().split(/\W+/);  //split the nodevalue to get words.
}).get(); //get the array of words.

console.log(res);

Demo

答案 1 :(得分:3)

function getText(target) {
    var wordArr = [];
    $('*',target).add(target).each(function(k,v) {
        var words  = $('*',v.cloneNode(true)).remove().end().text().split(/(\s+|\n)/);
        wordArr = wordArr.concat(words.filter(function(n){return n.trim()}));
    });
    return wordArr;
}

FIDDLE

答案 2 :(得分:1)

你可以这样做

function getwords(e){
    e.contents().each(function(){
        if ( $(this).children().length > 0 ) {
            getwords($(this))
        }
        else if($.trim($(this).text())!=""){
            words=words.concat($.trim($(this).text()).split(/\W+/))
        }
    });
}    

http://jsfiddle.net/R55eM/

答案 3 :(得分:1)

该问题假定单词不是由元素内部分隔的。如果您只是创建由空格和元素分隔的单词数组,则最终会得到:

Fr<b>e</b>d

被读为

['Fr', 'e', 'd']; 

要考虑的另一件事是标点符号。你怎么处理:“其中有三个:马克,苏和汤姆。他们不显着。一个 - 红头 - 在中间。”你删除所有标点符号吗?或者在修剪之前用白色空间替换它?如何重新加入由标记拆分的单词或可能是单词间或单词标点符号的字符?请注意,尽管在两边都有空格的单词之间写短划线很受欢迎,但“正确”的标点符号使用的是没有空格的短划线。

不那么简单......

无论如何,一种只使用递归拆分空间和元素的方法,可以在没有任何库支持的情况下在任何使用的浏览器中工作:

function getWords(element) {
  element = element || document.body;
  var node, nodes = element.childNodes;
  var words = [];
  var text, i=0;

    while (node = nodes[i++]) {

    if (node.nodeType == 1) {
      words = words.concat(getWords(node));

    } else if (node.nodeType == 3) {
      text = node.data.replace(/^\s+|\s+$/g,'').replace(/\s+/g,' ');
      words = !text.length? words : words.concat(text.split(/\s/));
    }
  }
  return words;
}

但它没有处理上述问题。

修改

要避免脚本元素,请更改:

    if (node.nodeType == 1) {

    if (node.nodeType == 1 && node.tagName.toLowerCase() != 'script') {

可以将任何应避免的元素添加到条件中。如果应该避免许多元素类型,你可以这样做:

var elementsToAvoid = {script:'script', button:'button'};
...
    if (node.nodeType == 1 && node.tagName && !(node.tagName.toLowerCase() in elementsToAvoid)) {