4

这些字符串可能是很长的段落,所以我不确定最好用空格分隔符分割整个字符串。我正在尝试获取前 10 个单词并将它们包装在一个跨度中:

'<span class="easing">' + string + '</span>'

然后重新加入原始拆分的后半部分。关于超有效方法的建议?它一次最多会影响页面上的三个段落。

已编辑

这是一个踢球者 - 拆分应该发生在第 9 个单词之后或第一个句子的末尾(如果该句子少于 9 个单词)。

例子

var origString = 'Coming into the world on Elvis’ birthday with a doctor named Presley seemed fortuitous until, wielding the silvery smooth scalpel in his aged unsteady hand, the doctor sliced through the walls of my mother’s uterus and into my unborn skin. Inside the warm soothing waters of my mother’s womb, inside the silent weightlessness, I was safe. Then the prick of cold steel marked the first in a series of rude awakenings. I was scarred for life even before birth.';
var newString = '<span="easing">Coming into the world on Elvis’ birthday with a doctor</span> named Presley seemed fortuitous until, wielding the silvery smooth scalpel in his aged unsteady hand, the doctor sliced through the walls of my mother’s uterus and into my unborn skin. Inside the warm soothing waters of my mother’s womb, inside the silent weightlessness, I was safe. Then the prick of cold steel marked the first in a series of rude awakenings. I was scarred for life even before birth.';

或者用一个简短的句子开始段落:

var origString = '“Is he okay? Tell me everything’s okay” she pleas, her desperate need to confirm my health competing with her own need for consolation.';
var newString = '<span class="easing">“Is he okay?</span> Tell me everything’s okay” she pleas, her desperate need to confirm my health competing with her own need for consolation.';
4

4 回答 4

2

考虑到您最多只能扫描大约 100 个字符(除非您有 URI 或非常长的单词),那么逐个字符扫描是非常理想的。您可以通过在某些地方使用 .indexOf() 来优化这一点,但是您会失去在检查每个可能终止句子的不同字符时所获得的东西。

function spanomatic ( str, words ) {
  var i, l, c;
  for ( i=0, l=str.length; i<l; i++ ) {
    c = str.charAt(i);
    if ( c == ' ' ) {
      if ( words-- <= 0 ) {
        str = '<span>'+str.substring(0,i)+'</span>'+str.substring(i);
        break;
      }
    }
    else if ( ('?!.;:').indexOf(c) != -1 ) {
      str = '<span>'+str.substring(0,i)+'</span>'+str.substring(i);
      break;
    }
  }
  return str;
}

spanomatic ( 'Pass your string here', 9 );

(上面的代码假定您的文本将始终以正确的语法终止(即至少包含一个?!.;:) - 如果不是,那么少于 9 个单词的段落可能会以无跨度结尾。这可能是但是通过一些更改修复...)

给未来读者的注意事项

如果您想要一种“超级高效”的字符串搜索方式,请避免使用正则表达式(除非您真的需要它们的能力)。这个问题的公认答案是简洁并且很好地组合了函数 - 不要误会我的意思 - 但它比使用 for 循环扫描字符串慢大约 70% (至少在我对 FireFox 和 Chrome 的测试中) ......甚至在将正则表达式定义移到 Bergi 函数之外进行比较时(即使用预编译的正则表达式而不是每次调用函数时都重新创建它们)

http://jsperf.com/compare-regexp-vs-char-scanning

于 2012-09-15T19:35:21.597 回答
1
return string.replace(/.+?[,.?!]|.+$/, function(match, index, string){
    var words = match.split(/\s+/);
    words[ words.length<10 ? words.length-1 : 9 ] += '</span>';
    return '<span class="easing">' + words.join(" ");
});

这匹配第一个类似句子的东西(或整个字符串 - 除非换行符),并在该跨度中包装它的前 10 个单词。适用于您的样本输入,也适用于较小的输入。…|.*$返回空字符串的空字符串,如果需要空跨度,请将正则表达式更改为。

于 2012-09-15T18:59:26.290 回答
0

这里。不过,这有点像代码高尔夫。对不起。

$( 'p' ).html(function ( i, text ) {
    var re = /(.+?)\s/g, c = 0, res;   
    while ( res = re.exec( text ) ) if ( ++c === 10 || res[1].slice( -1 ) === '.' ) break;

    var p = re.lastIndex;
    return '<span class="easing">' + text.slice( 0, p ) + '</span>' + text.slice( p );  
});

现场演示:http: //jsfiddle.net/3DaEV/

于 2012-09-15T19:38:46.177 回答
0

这段代码怎么样:

var str = 'asda adsfadsf asdfadfadsf adsfsdafadf. adfadfadfad adfadfdaf adfadfadf adfadf \afsgasfggasfg SFGDFGDSFGH dfghdsghdgas hadghdagh';

var sentences = [], words = str.split(' ');
for (var i = 0; i < 9; i++) {
    if (words[i].lastIndexOf('.') !== -1) {
        sentences.push(words[i]);
        break;    
    } else {
        sentences.push(words[i]);
    }        
}

words.slice(sentences.length, words.length);


$('<span>' + sentences.join(' ') + '</span>').appendTo($('#log'));

我把它放在小提琴下面,你可以测试一下。您可能希望在循环中使用 arr1 的其余部分执行此操作。

更新:

如果它不仅是句号,还有 ?!:; 等。然后创建一个RegExp并测试而不是做lastIndexOf('.')

于 2012-09-15T19:13:04.590 回答