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

Posted

技术标签:

【中文标题】如何删除字符串周围的特定字符?【英文标题】:How to remove specific character surrounding a string? 【发布时间】:2016-07-23 07:09:18 【问题描述】:

我有这个字符串:

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。现在我想知道我是否可以在 JS 中使用trim() 来做到这一点。


应该注意I can do that using regex,但老实说,我讨厌这种工作的正则表达式。有没有更好的办法?


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

【问题讨论】:

trim 删除空格,这不是空格 我现在意识到了。为什么不将0,1length-1,length 分成子字符串并扫描?(并删除空格),然后将字符串连接回主字符串? @Shafizadeh 您的字符串的开头和结尾是否有任何数量的?,还是只是? [text] ? 这个真的不清楚。 ??? Test ?? Test ?? ??? Test ?? ? 或其他一些组合的输出应该是什么? 投票重新开放。我仍然无法理解人们在现实世界中的高级程度如何,但投票结束这样一个易于理解的编程问题。 【参考方案1】:

Javascript 的 trim 方法只删除空格,不带参数。对于自定义修剪,您必须制作自己的功能。正则表达式会为它提供一个快速的解决方案,如果您不想经历正则表达式创建过程的麻烦,您可以在w3schools 上找到自定义修剪的实现。 (您只需将其调整为 filter ? 而不是空格

【讨论】:

【参考方案2】:

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

更新:(注:作者要求修剪周围的字符)

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"

【讨论】:

不知道这个答案是否正确,但很高兴看到有人真正阅读了这个问题(之前的四五个答案没有,因此被删除或/和投反对票)。 @RomanPerekhrest 也许str.slice(2, -2) 会比str.slice(1, -1).trim() 快...? ...如果不是含糊其辞,您将不会根据不同的假设得到不同的答案。据我们所知,如果您有"? ? foo ? bar ? ?",则可能需要从每一端保留第二个?。结果应该是"foo ? bar" 还是"? foo ? bar ?" @squint 是的,你是对的......我的问题很模糊......!我想要 this 输出作为您的示例。【参考方案3】:

没有正则表达式:

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

分步说明:

    检查字符串是否至少有 2 个字符长以及是否被特定字符包围; 如果是,则先对其进行切片以去除周围的字符,然后对其进行修剪以去除空格; 如果不直接退货。

如果您对该语法感到奇怪,那就是 Arrow Function 和 ternary operator。 顺便说一下,括号在三元中是多余的。

使用示例:

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

【讨论】:

@Shafizadeh 请注意,此代码要求前导字符和尾随字符的数量始终为两个(每端一个)。它不会修剪所有'!' 或空格中的'!! Plop !!',从而导致'! Plop !'【参考方案4】:

搜索字符掩码并返回其余的没有。

本建议使用bitwise not~操作符进行检查。

~ 是 bitwise not operator。它非常适合与indexOf() 一起使用,因为indexOf 如果找到索引0 ... n 则返回,否则返回-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 '));

【讨论】:

很好,但是使用两个修剪索引并在最后执行一次slice 会更有效。 @georg,如果索引重叠,则需要再次测试。 一个问题,JS中~是什么意思? @Shafizadeh,它是按位非运算符,请参阅编辑。 请将 while 更改为:while(s.length &gt; 0 &amp;&amp; ~mask.indexOf(s[0])) 以防止索引越界异常【参考方案5】:

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

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(' ');

【讨论】:

PHP 的 trim 函数也可以trim("??string??", "??") // string. 我的目标不是创建一个与 php trim 函数具有相同行为的函数,但我认为我可以添加该功能。 @Xorifelse 有兴趣知道如何在 JS 中有效地使用 PHP 函数而无需复制 PHP 函数(感兴趣,因为我没有做过很多 JS,所以会很有趣知道)? @Xorifelse:更新了我的答案,现在可以修剪多字符字符串。 @cybermonkey 绝对是。这就是为什么它应该尽可能在客户端上完成。 (对于需要存储在某个地方的数据,再次在服务器上,因为来自任何客户端的数据都必须被认为是不安全的。)【参考方案6】:

这是一种检查索引越界的方法,并且只调用一次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"

【讨论】:

【参考方案7】:

简单使用:

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

console.log(text)

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

使用正则表达式

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

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

【讨论】:

【参考方案10】:

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

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

【讨论】:

以上是关于如何删除字符串周围的特定字符?的主要内容,如果未能解决你的问题,请参考以下文章

Php - 如何在 QueryPath 中删除/删除带有特定字符串的标签?

如何在 PHP 中删除字符串末尾的所有特定字符?

如何以编程方式从 NSString 中删除特定字符?

Python如何删除文本文件中特定字符串之后或之前的特定行数

如何删除所有出现的特定字符串一个字符串? [复制]

如何从字符串中删除特定单词?