截取字符串的方法:使用JavaScript直接截取

245

我想使用JavaScript截取一个动态加载的字符串。它是一个URL,因此没有空格,而且我只关心字符,不关心单词边界。

以下是我的代码:

var pathname = document.referrer; //wont work if accessing file:// paths
document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"

2
你想截取哪一部分?你的例子没有很好地表达意图。 - Larsenal
1
哦,好的 - 我想要在一定数量的字符处截断URL,这样当我设置“foo”的innerHTML时,如果它太长,它就不会流出div。 - Bob
1
但是-只是innerHTML,不是变量pathname本身。 - Bob
1
为什么不直接使用CSS来隐藏div的溢出内容?overflow: hidden - Samuel
3
因为从 UI 设计的角度来看,如果用户期望能够看到他们刚访问过的网址(document.referrer),而我正在对其进行缩短处理,我需要向用户指示他们只能够看到部分网址,并且这并不是一个错误。除此之外,你提出的方法会将字符一分为二,看起来非常糟糕。 - Bob
1
你应该使用CSS。 - zamzam
16个回答

441

使用 substring 方法:


var length = 3;
var myString = "ABCDEFG";
var myTruncatedString = myString.substring(0,length);
// The value of myTruncatedString is "ABC"

所以在你的情况下:

var length = 3;  // set to the number of characters you want to keep
var pathname = document.referrer;
var trimmedPathname = pathname.substring(0, Math.min(length,pathname.length));

document.getElementById("foo").innerHTML =
     "<a href='" + pathname +"'>" + trimmedPathname + "</a>"

2
如果你想要从0开始的子字符串,那么substr函数将会用比原来少3个字符的方式做完全相同的事情 ;) - jackocnr
3
如果字符串长度比length短,substr函数的表现会很奇怪——它会返回空值。 - RozzA
1
如果你的“string”是一个数字,你还需要插入.toString().将其转换为substring()可以处理的字符串。 - not2qubit
1
MDN文档比W3schools更好。 - BigRon

46

这里有一个你可以使用的方法。这是FreeCodeCamp挑战中的一个答案:

function truncateString(str, num) {
  if (str.length > num) {
    return str.slice(0, num) + "...";
  } else {
    return str;
  }
}

1
这可能会返回一个比num更长的字符串,因为“...”。如果字符串长度小于三,您也不想添加“...”这是更好的方法,抱歉不知道如何在注释中格式化它:function truncate(input, length) { if (input.length <= length) return input; if (length < 3) return input.substring(0, length); return input.substring(0, length - 3) + '...'; } - Andy

20

更新的ES6版本

const truncateString = (string = '', maxLength = 50) => 
  string.length > maxLength 
    ? `${string.substring(0, maxLength)}…`
    : string

// demo the above function
alert(truncateString('Hello World', 4));


这总是调用子字符串,即使可能并不需要... - Clint Eastwood
@ClintEastwood 给出了很好的反馈,我已经更新了答案。检查字符串长度与最大长度相比,也意味着我可以删除 showDots 常量和三元运算符,使其更加整洁。谢谢。 - Sam Logan

18

是的,使用substring。你不需要进行Math.min操作;如果截取子字符串时索引大于原字符串长度,则会截取至原长度。

但是!

document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"

这是一个错误。如果document.referrer中有撇号或其他在HTML中具有特殊意义的字符,会怎样呢?最坏的情况是,referrer中的攻击者代码可能会注入JavaScript到您的页面中,这是一种XSS安全漏洞。

虽然可以手动转义pathname中的字符以防止发生这种情况,但这有点麻烦。最好使用DOM方法而不是调整innerHTML字符串。

if (document.referrer) {
    var trimmed= document.referrer.substring(0, 64);
    var link= document.createElement('a');
    link.href= document.referrer;
    link.appendChild(document.createTextNode(trimmed));
    document.getElementById('foo').appendChild(link);
}

我有点困惑,你的解决方案是如何避免安全漏洞的? - Bob
11
当你使用DOM方法(如'createTextNode'和'.href =')时,你直接设置了真实的底层纯文本值。当你编写HTML时,无论是在HTML文件中还是通过innerHTML,你必须遵守HTML转义规则。因此,虽然'createTextNode('A<B&C')'没问题,但在使用innerHTML时,你需要这样写:'innerHTML= 'A<B&C''。 - bobince

14

以下代码截断一个字符串,不会将单词分开,而是丢弃截断位置所在的单词。完全基于Sugar.js源码。

function truncateOnWord(str, limit) {
        var trimmable = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF';
        var reg = new RegExp('(?=[' + trimmable + '])');
        var words = str.split(reg);
        var count = 0;
        return words.filter(function(word) {
            count += word.length;
            return count <= limit;
        }).join('');
    }

3
如果结果不等于字符串,则添加省略号"...",这样会很好。 - Leo Caseiro

10

我想提一下 Sugar.js。它有一个相当智能的truncate方法。

根据文档

截取字符串。除非split为true,否则truncate不会将单词拆开,而是丢弃截断发生的那个单词。

例如:

'just sittin on the dock of the bay'.truncate(20)

输出:

just sitting on...

12
Sugar是一个Javascript库,它扩展了原生对象。在JavaScript中扩展原生对象通常被认为是一个坏主意™。 - Jezen Thomas
2
@JezenThomas 有时候不好的想法是最合适的想法。 - viditkothari

4

是的,substring非常好用:

stringTruncate('Hello world', 5); //output "Hello..."
stringTruncate('Hello world', 20);//output "Hello world"

var stringTruncate = function(str, length){
  var dots = str.length > length ? '...' : '';
  return str.substring(0, length)+dots;
};

4

一行ES6解决方案

与其只是截断字符串,如果字符串长度超过给定长度,它还会添加一个结束字符串。

const limit = (string, length, end = "...") => {
    return string.length < length ? string : string.substring(0, length) + end
}

limit('Hello world', 5) // Hello...

2

要将字符串截断到特定长度,请在JavaScript中使用以下一行箭头函数:

const truncate = (str, len) => str.slice?.(0, len);
    
console.log(truncate("Hello, World!", 5));
// Expected Output: Hello

上述函数使用了String.prototype.slice方法,该方法可以从字符串中取出一部分并返回一个新的字符串,而不改变原始字符串。

你可能想在切片后删除 ? 字符。 - cak3_lover

2
var str = "Anything you type in.";
str.substring(0, 5) + "" //you can type any amount of length you want

2
这将在即使没有发生截断的情况下添加省略号。 - Draculater
@Draculater,我编辑了答案。现在可以了吗? - Haramine Sinan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接