如何删除字符串周围的特定字符?

How to remove specific character surrounding a string?

我有这个字符串:

var str = "? this is a ? test ?";

现在我想得到这个:

var newstr = "this is a ? test";

如你所见,我只想删除 周围的那些 (在开头和结尾) 那个字符串 (不在中间)字符串)。如何使用 JavaScript 做到这一点?

这是我尝试过的:

var str = "? this is a ? test ?";
var result = str.trim("?");
document.write(result);

因此,如您所见,它不起作用。事实上,我是一名 PHP 开发人员并且 trim() works well in PHP。现在我想知道我是否可以使用 trim() 在 JS 中做到这一点。


应该注意 I can do that using regex,但老实说,我讨厌这种工作的正则表达式。无论如何有更好的解决方案吗?


编辑: 正如评论中提到的那样,我需要删除字符串周围的 ? 和空格。

Javascript 的 trim 方法仅删除空格,不带任何参数。对于自定义 trim,您必须创建自己的函数。 Regex 可以快速解决这个问题,如果您不想经历 regex 创建过程的麻烦,您可以在 w3schools 上找到自定义 trim 的实现。 (你只需要调整它来过滤 ? 而不是 whitespace

使用 Array.indexOfArray.lastIndexOfArray.slice 函数的简单方法:

更新:(注:作者已要求trim周边 个字符)

function trimChars(str, char){
    var str = str.trim();

    var checkCharCount = function(side) {
        var inner_str = (side == "left")? str : str.split("").reverse().join(""),
            count = 0;

        for (var i = 0, len = inner_str.length; i < len; i++) {
            if (inner_str[i] !== char) {
                break;
            }
            count++;
        }
        return (side == "left")? count : (-count - 1);
    };

    if (typeof char === "string" 
            && str.indexOf(char) === 0
            && str.lastIndexOf(char, -1) === 0) {
        str = str.slice(checkCharCount("left"), checkCharCount("right")).trim();
    }

    return str;
}

var str = "???? this is a ? test ??????";

console.log(trimChars(str, "?"));   // "this is a ? test"

没有正则表达式:

uberTrim = s => s.length >= 2 && (s[0] === s[s.length - 1])?
  s.slice(1, -1).trim() 
  : s;

分步说明:

  1. 检查字符串是否至少为 2 个字符,是否被特定字符包围;
  2. 如果是,则先将其切片以删除周围的字符,然后 trim 将其删除空格;
  3. 如果不只是return它。

万一你被那个语法搞糊涂了,它是一个 Arrow Function and a ternary operator.
顺便说一下,括号在三进制中是多余的。

使用示例:

uberTrim(''); // ''
uberTrim(' Plop! '); //'Plop!'
uberTrim('! ...What is Plop?!'); //'...What is Plop?'

搜索字符掩码,return 其余不搜索。

本提案使用bitwise not~运算符进行校验。

~ is a bitwise not operator. It is perfect for use with indexOf(), because indexOf returns if found the index 0 ... n and if not -1:

value  ~value   boolean
 -1  =>   0  =>  false
  0  =>  -1  =>  true
  1  =>  -2  =>  true
  2  =>  -3  =>  true
  and so on 

function trim(s, mask) {
    while (~mask.indexOf(s[0])) {
        s = s.slice(1);
    }
    while (~mask.indexOf(s[s.length - 1])) {
        s = s.slice(0, -1);
    }
    return s;
}

console.log(trim('??? this is a ? test ?', '? '));
console.log(trim('abc this is a ? test abc', 'cba '));

一个可能的解决方案是使用递归函数删除不需要的前导和尾随字符。这不使用正则表达式。

function ltrim(char, str) {
    if (str.slice(0, char.length) === char) {
        return ltrim(char, str.slice(char.length));
    } else {
        return str;
    }
}

function rtrim(char, str) {
    if (str.slice(str.length - char.length) === char) {
        return rtrim(char, str.slice(0, 0 - char.length));
    } else {
        return str;
    }
}

当然这只是众多可能解决方案中的一种。函数 trim 将同时使用 ltrimrtrim.

之所以 char 是第一个参数,第二个是需要清理的字符串,是为了更容易将其更改为函数式编程风格的函数,如下所示 (ES 2015):

function ltrim(char) {
    (str) => {
        <body of function>
    }
}

// No need to specify str here
function ltrimSpaces = ltrim(' ');

这是一种检查索引越界的方法,只调用一次 substring:

String.prototype.trimChars = function(chars) {
  var l = 0;
  var r = this.length-1;
  while(chars.indexOf(this[l]) >= 0 && l < r) l++;
  while(chars.indexOf(this[r]) >= 0 && r >= l) r--;
  return this.substring(l, r+1);
};

示例:

var str = "? this is a ? test ?";

str.trimChars(" ?");  // "this is a ? test"

只需使用:

let text = '?? something ? really ??'
text = text.replace(/^([?]*)/g, '')
text = text.replace(/([?]*)$/g, '')

console.log(text)

使用 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);
}

使用正则表达式

'? this is a ? test ?'.replace(/^[? ]*(.*?)[? ]*$/g, '')

你可能讨厌正则表达式,但找到解决方案后你会感觉很酷:)

这在一行代码中 returns 你想要的输出:

"? this is a ? test ?".slice(1).slice(0,-1).trim();