【问题标题】:Regex remove all leading and trailing special characters?正则表达式删除所有前导和尾随特殊字符?
【发布时间】:2020-02-16 12:53:44
【问题描述】:

假设我在 javascript 中有以下字符串:

&a.b.c. &a.b.c& .&a.b.c.&. *;a.b.c&*. a.b&.c& .&a.b.&&dc.& &ê.b..c&

我想从所有单词中删除所有前导和尾随特殊字符(任何不是字母数字或其他语言的字母)。

所以字符串应该看起来像

a.b.c a.b.c a.b.c a.b.c a.b&.c a.b.&&dc ê.b..c

注意字母数字之间的特殊字符是如何留下的。最后的ê 也留下了。

【问题讨论】:

    标签: javascript regex regex-greedy


    【解决方案1】:

    这样的事情可能会有所帮助:

    const string = '&a.b.c. &a.b.c& .&a.b.c.&. *;a.b.c&*. a.b&.c& .&a.b.&&dc.& &ê.b..c&';
    const result = string.split(' ').map(s => /^[^a-zA-Z0-9ê]*([\w\W]*?)[^a-zA-Z0-9ê]*$/g.exec(s)[1]).join(' ');
    console.log(result);

    请注意,这不是一个单一的正则表达式,而是使用 JS 帮助代码。

    粗略解释:我们先把字符串拆分成字符串数组,用空格分隔。然后我们通过剥离来转换每个子字符串 前导和尾随特殊字符。我们通过捕获所有带有[^a-zA-Z0-9ê]* 的特殊字符来做到这一点,因为前面的^ 字符它匹配所有列出的字符除了,所以所有的特殊字符。在这两组之间,我们使用([\w\W]*?) 捕获所有相关字符。 \w 捕获单词,\W 捕获非单词,因此 \w\W 捕获所有可能的字符。通过在* 之后附加?,我们使量词* 变得懒惰,这样该组就会在下一个捕获尾随特殊字符的组捕获某些内容时停止捕获。我们还以^ 符号开始正则表达式并以$ 符号结束它以捕获整个字符串(它们分别将锚点设置在字符串的开头和结尾)。然后我们使用.exec(s)[1] 对子字符串执行正则表达式,并在我们的转换函数中返回第一个捕获组结果。请注意,如果子字符串不包含正确的字符,这可能为 null。最后我们用空格连接子字符串。

    【讨论】:

    • 这不会留下最后一个ê
    • 是的,这就是我在帖子中解释的内容。无论如何,我已经将它编辑为也留下ê 字符。您可以编辑特殊字符捕获组以指定您认为是特殊字符的字符。
    • 这很好用。唯一的问题是ê 是可变的。就像它可以有任何这些类型的字母一样。以à 为例。
    • 好吧,您可以明确列出所有可能的特殊字符,对于这些字母的通用匹配,您需要匹配 unicode 代码的范围。参见例如stackoverflow.com/a/280762/2692307 关于如何匹配 unicode 范围。
    • 这是不正确的。它从字符串中间删除特殊字符。使用像“This + That”这样的简单字符串进行测试
    【解决方案2】:

    这个正则表达式应该做你想做的事。它寻找

    • 行首,或第 1 组中捕获的一些空格 (^| +)
    • 一些符号字符[!-\/:-@\[-``\{-~]*
    • 在第 2 组中捕获的最少数量的非空格字符 ([^ ]*?)
    • 一些符号字符[!-\/:-@\[-``\{-~]*
    • 后跟空格或行尾(使用正向前瞻)(?=\s|$)

    匹配项仅替换为第 1 组和第 2 组(符号之间的间距和字符)。

    let str = '&a.b.c. &a.b.c& .&a.b.c.&. *;a.b.c&*. a.b&.c& .&a.b.&&dc.& &ê.b..c&';
    str = str.replace(/(^| +)[!-\/:-@\[-`\{-~]*([^ ]*?)[!-\/:-@\[-`\{-~]*(?=\s|$)/gi, '$1$2');
    console.log(str);

    请注意,如果您想单独保留一串标点符号(例如Apple & Sauce),您应该更改第二个捕获组以坚持存在一个或多个非空格字符(([^ ]+?) ) 而不是 none,并在标点字符的初始匹配后添加一个前瞻,以断言下一个字符不是标点:

    let str = 'Apple &&& Sauce; -This + !That!';
    str = str.replace(/(^| +)[!-\/:-@\[-`\{-~]*(?![!-\/:-@\[-`\{-~])([^ ]+?)[!-\/:-@\[-`\{-~]*(?=\s|$)/gi, '$1$2');
    console.log(str);

    【讨论】:

    • 这似乎是最好的单行方式,它也非常适合变音符号。谢谢!
    • @PranoyC 不用担心 - 我很高兴能提供帮助。
    • 这会删除字符串中间的字符。它应该只从结尾和开头删除。使用“Apple & Sauce”或“This + That”等字符串进行测试
    • @siefix 感谢您 留下评论以配合(我认为是)您的反对意见。我相信您描述的行为是 OP 要求的:“我想从 all 单词中删除所有前导和尾随特殊字符”,而不仅仅是字符串的结尾和开头。现在我们可以争论是否应该单独剥离&+;它们与问题中的数据模式不匹配,但我认为这是对问题措辞的合理解释。无论如何,我已经用一个不会自行删除标点字符串的正则表达式更新了答案。
    • @Nick 感谢更新和其他解决方案。是的,我将其解释为每个都是一个单独的不同单词,并且 OP 希望在中间保留特殊字符(例如“a.b.&&dc”)。两边都能看到。
    【解决方案3】:

    a-zA-Z\u00C0-\u017F 用于捕获所有有效字符,包括变音符号。

    以下是用于捕获每个单词的单个正则表达式。其逻辑是,它将寻找第一个有效字符作为捕获组的开头,然后将空格字符或字符串终止符之前的最后一个无效字符序列作为捕获组的结尾。

    const myRegEx = /[^a-zA-Z\u00C0-\u017F]*([a-zA-Z\u00C0-\u017F].*?[a-zA-Z\u00C0-\u017F]*)[^a-zA-Z\u00C0-\u017F]*?(\s|$)/g;  
    let myString = '&a.b.c. &a.b.c& .&a.b.c.&. *;a.b.c&*. a.b&.c& .&a.b.&&dc.& &ê.b..c&'.replace(myRegEx, '$1$2');
    console.log(myString);

    【讨论】:

      猜你喜欢
      • 2016-05-26
      • 2011-03-19
      • 1970-01-01
      • 2018-07-24
      • 2021-10-11
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多