修剪字符串中的特定字符

fub*_*ubo 92 javascript string trim

什么是与此方法等效的JavaScriptC#:

var x = "|f|oo||"; 
var y = x.Trim('|'); //  "f|oo"
Run Code Online (Sandbox Code Playgroud)

C#仅在字符串的开头结尾处修剪所选字符!

lea*_*eaf 116

一行就足够了:

var x = '|f|oo||';
var y = x.replace(/^\|+|\|+$/g, '');
document.write(x + '<br />' + y);
Run Code Online (Sandbox Code Playgroud)

^\|+   beginning of the string, pipe, one or more times
|      or
\|+$   pipe, one or more times, end of the string
Run Code Online (Sandbox Code Playgroud)

在一个功能:

function trim (s, c) {
  if (c === "]") c = "\\]";
  if (c === "\\") c = "\\\\";
  return s.replace(new RegExp(
    "^[" + c + "]+|[" + c + "]+$", "g"
  ), "");
}

chars = ".|]\\";
for (c of chars) {
  s = c + "foo" + c + c + "oo" + c + c + c;
  console.log(s, "->", trim(s, c));
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*rke 33

Update: Was curious around the performance of different solutions and so I've updated a basic benchmark here: https://www.measurethat.net/Benchmarks/Show/12738/0/trimming-leadingtrailing-characters

Some interesting and unexpected results running under Chrome. https://www.measurethat.net/Benchmarks/ShowResult/182877

+-----------------------------------+-----------------------+
| Test name                         | Executions per second |
+-----------------------------------+-----------------------+
| Index Version (Jason Larke)       | 949979.7 Ops/sec      |
| Substring Version (Pho3niX83)     | 197548.9 Ops/sec      |
| Regex Version (leaf)              | 107357.2 Ops/sec      |
| Boolean Filter Version (mbaer3000)| 94162.3 Ops/sec       |
| Spread Version (Robin F.)         | 4242.8 Ops/sec        |
+-----------------------------------+-----------------------+
Run Code Online (Sandbox Code Playgroud)

Please note; tests were carried out on only a single test string (with both leading and trailing characters that needed trimming). In addition, this benchmark only gives an indication of raw speed; other factors like memory usage are also important to consider.


If you're dealing with longer strings I believe this should outperform most of the other options by reducing the number of allocated strings to either zero or one:

+-----------------------------------+-----------------------+
| Test name                         | Executions per second |
+-----------------------------------+-----------------------+
| Index Version (Jason Larke)       | 949979.7 Ops/sec      |
| Substring Version (Pho3niX83)     | 197548.9 Ops/sec      |
| Regex Version (leaf)              | 107357.2 Ops/sec      |
| Boolean Filter Version (mbaer3000)| 94162.3 Ops/sec       |
| Spread Version (Robin F.)         | 4242.8 Ops/sec        |
+-----------------------------------+-----------------------+
Run Code Online (Sandbox Code Playgroud)

Or if you want to trim from a set of multiple characters:

function trim(str, ch) {
    var start = 0, 
        end = str.length;

    while(start < end && str[start] === ch)
        ++start;

    while(end > start && str[end - 1] === ch)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trim('|hello|world|', '|'); // => 'hello|world'
Run Code Online (Sandbox Code Playgroud)

EDIT: For fun, trim words (rather than individual characters)

function trimAny(str, chars) {
    var start = 0, 
        end = str.length;

    while(start < end && chars.indexOf(str[start]) >= 0)
        ++start;

    while(end > start && chars.indexOf(str[end - 1]) >= 0)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimAny('|hello|world   ', [ '|', ' ' ]); // => 'hello|world'
// because '.indexOf' is used, you could also pass a string for the 2nd parameter:
trimAny('|hello| world  ', '| '); // => 'hello|world'
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢这个解决方案,因为它实际上非常高效,而不仅仅是简短。 (3认同)

小智 32

如果我理解得很好,你只想在字符串的开头或结尾处删除特定字符(例如:"|| fo || oo ||||"应该变为"foo || oo") .您可以创建ad hoc函数,如下所示:

function trimChar(string, charToRemove) {
    while(string.charAt(0)==charToRemove) {
        string = string.substring(1);
    }

    while(string.charAt(string.length-1)==charToRemove) {
        string = string.substring(0,string.length-1);
    }

    return string;
}
Run Code Online (Sandbox Code Playgroud)

我用下面的代码测试了这个函数:

var str = "|f|oo||";
$( "#original" ).html( "Original String: '" + str + "'" );
$( "#trimmed" ).html( "Trimmed: '" + trimChar(str, "|") + "'" );
Run Code Online (Sandbox Code Playgroud)

  • 对于垃圾收集器来说,这将是一个有趣的测试,但我不建议让您的客户接受它。 (5认同)

nee*_*lsg 15

您可以使用正则表达式,例如:

var x = "|f|oo||";
var y = x.replace(/^[\|]+|[\|]+$/g, "");
alert(y); // f|oo
Run Code Online (Sandbox Code Playgroud)

更新:

如果您希望将其概括为函数,可以执行以下操作:

var escapeRegExp = function(strToEscape) {
    // Escape special characters for use in a regular expression
    return strToEscape.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};

var trimChar = function(origString, charToTrim) {
    charToTrim = escapeRegExp(charToTrim);
    var regEx = new RegExp("^[" + charToTrim + "]+|[" + charToTrim + "]+$", "g");
    return origString.replace(regEx, "");
};

var x = "|f|oo||";
var y = trimChar(x, "|");
alert(y); // f|oo
Run Code Online (Sandbox Code Playgroud)


Rob*_* F. 14

让这个问题保持最新:

这是我使用ES6扩展运算符选择正则表达式函数的方法.

function trimByChar(string, character) {
  const first = [...string].findIndex(char => char !== character);
  const last = [...string].reverse().findIndex(char => char !== character);
  return string.substring(first, string.length - last);
}
Run Code Online (Sandbox Code Playgroud)

  • 我知道正则表达式在这里过大,但是为什么要选择这种特定实现? (2认同)
  • 这个实现是因为我个人觉得它可读性很好。没有正则表达式仅仅是因为正则表达式引擎中的决策“树”要大得多。尤其是因为用于修剪的正则表达式包含导致正则表达式引擎内回溯的查询字符。此类引擎通常将模式编译为字节码,类似于机器指令。然后引擎执行代码,从指令跳转到指令。当一条指令失败时,它会回溯以找到另一种匹配输入的方法。因此,发生的事情比 nec 多得多。 (2认同)

mar*_*lar 8

这可以一次修剪几个字符:

String.prototype.trimChars = function (c) {
  var re = new RegExp("^[" + c + "]+|[" + c + "]+$", "g");
  return this.replace(re,"");
}

var x = "|f|oo||"; 
x =  x.trimChars('|'); // f|oo

var y = "..++|f|oo||++..";
y = y.trimChars('|.+'); // f|oo

var z = "\\f|oo\\"; // \f|oo\

// For backslash, remember to double-escape:
z = z.trimChars("\\\\"); // f|oo
Run Code Online (Sandbox Code Playgroud)


mba*_*000 5

A regex-less version which is easy on the eye:

const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars);
Run Code Online (Sandbox Code Playgroud)

For use cases where we're certain that there's no repetition of the chars off the edges.


小智 5

const trim = (str, char) => {
    let i = 0;
    let j = str.length-1;
    while (str[i] === char) i++;
    while (str[j] === char) j--;
    return str.slice(i,j+1);
}
console.log(trim('|f|oo|', '|')); // f|oo
Run Code Online (Sandbox Code Playgroud)

非正则表达式解决方案。两个指针:(i开始)和j(结束)。仅当指针匹配 char 时才移动指针,不匹配时停止。返回剩余的字符串。