从字符串中修剪特定字符

IT技术 javascript string trim
2021-01-15 17:55:09

与此方法等效JavaScript是什么C#

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

C#只在字符串开头结尾修剪所选字符

6个回答

一行就够了:

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

^     beginning of the string
\|+   pipe, one or more times
|     or
\|+   pipe, one or more times
$     end of the string

一个通用的解决方案:

function trim (s, c) {
  if (c === "]") 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));
}

参数c应为字符(长度为 1 的字符串)。

正如评论中提到的,支持多个字符可能很有用,因为例如修剪多个类似空格的字符是很常见的。为此,MightyPork建议if用以下代码行替换s:

c = c.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');

这部分[-/\\^$*+?.()|[\]{}]是正则表达式语法中的一组特殊字符,$&是一个占位符,代表匹配字符,表示replace函数对特殊字符进行转义。在浏览器控制台中尝试:

> "{[hello]}".replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
"\{\[hello\]\}"
@MightyPork 我试过- ( trim("-foo--oo---", '-')),它似乎没有引起任何问题。无论如何,修剪多种类型的空格字符的想法听起来很有趣,我将在原始答案下方总结您的想法。
2021-03-18 17:55:09
将“通用解决方案”中的两个 if 替换为正则表达式转义,以便安全地支持多个字符: c = c.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
2021-03-27 17:55:09
哦,它仍然不支持多个字符。想象一下,您想要修剪制表符和空格,以便使用"\t "这种用例
2021-03-29 17:55:09
@MightyPork 只^丢失了。谢谢。
2021-04-04 17:55:09
我认为你最好完全逃脱以确保安全,另一个会引起问题的角色是 -
2021-04-11 17:55:09

如果我理解得很好,您只想删除位于字符串开头或结尾的特定字符(例如:||fo||oo||||应该变为foo||oo)。您可以按如下方式创建临时功能:

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;
}

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

var str = "|f|oo||";
$( "#original" ).html( "Original String: '" + str + "'" );
$( "#trimmed" ).html( "Trimmed: '" + trimChar(str, "|") + "'" );
对于垃圾收集器来说,这将是一个有趣的测试,但我不建议让您的客户接受它。
2021-04-02 17:55:09
我最喜欢这个答案的原因是:我能读懂它。垃圾收集器将正常工作。有了这个解决方案,我可以应用字符串而不是字符,而且我仍然可以阅读和理解它的作用,而无需深入研究 Regex 语法。
2021-04-11 17:55:09

更新:对不同解决方案的性能很好奇,所以我在这里更新了一个基本的基准:https : //www.measurethat.net/Benchmarks/Show/12738/0/trimming-leadingtrailing-characters

在 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        |
+-----------------------------------+-----------------------+

请注意; 仅对单个测试字符串(需要修剪的前导和尾随字符)进行测试。此外,该基准测试仅给出原始速度的指示;其他因素(如内存使用情况)也很重要。


如果您正在处理更长的字符串,我相信通过将分配的字符串数量减少到零或一,这应该优于大多数其他选项:

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'

或者,如果您想从一组多个字符中修剪:

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'

编辑:为了好玩,修剪单词(而不是单个字符)

// Helper function to detect if a string contains another string
//     at a specific position. 
// Equivalent to using `str.indexOf(substr, pos) === pos` but *should* be more efficient on longer strings as it can exit early (needs benchmarks to back this up).
function hasSubstringAt(str, substr, pos) {
    var idx = 0, len = substr.length;

    for (var max = str.length; idx < len; ++idx) {
        if ((pos + idx) >= max || str[pos + idx] != substr[idx])
            break;
    }

    return idx === len;
}

function trimWord(str, word) {
    var start = 0,
        end = str.length,
        len = word.length;

    while (start < end && hasSubstringAt(str, word, start))
        start += word.length;

    while (end > start && hasSubstringAt(str, word, end - len))
        end -= word.length

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

// Usage:
trimWord('blahrealmessageblah', 'blah');
如果您想进行完整的 C# 修剪替换,您可以将此答案作为扩展方法(原型扩展?)...如果您不将其作为扩展,String.prototype.trimChar = String.prototype.trimChar || function (chr) { // ...您也可能会嗅探trim(undefined, "|")
2021-03-15 17:55:10
我更喜欢这个解决方案,因为它实际上是有效的,而不仅仅是简短的。
2021-04-09 17:55:10
我同意它应该是首选。取代我给出的答案。
2021-04-09 17:55:10

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

var x = "|f|oo||";
var y = x.replace(/^\|+|\|+$/g, "");
alert(y); // f|oo

更新:

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

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

一个简单的无正则表达式版本:

const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars);

对于我们确定边缘字符没有重复的用例。

这不是修剪,这是字符替换
2021-03-20 17:55:10
如果字符串中间有重复的字符,这将不起作用。trim("|first||last|", "|")返回first|last(中间只有一根管子)。
2021-04-03 17:55:10
你是对的,这就是我试图说的“边缘字符不重复”。
2021-04-10 17:55:10
非常有趣......所以 split 返回 undefined 元素等于每个被拆分的分隔符 const trim = (str, chars) => str.split(chars).filter(x => { Boolean(x); console.log(typeof(x), x, Boolean(x)); }).join(chars); const str = "#//#//abc#//test#//end#//"; console.log(trim(str, '#//'));
2021-04-12 17:55:10
很棒的解决方案!我需要从前导和尾随斜杠中清除路径 ```` path.split('/').filter(Boolean).join('/') ```` 这对我来说很棒:-) 非常感谢!
2021-04-14 17:55:10