用于非alnum字符的字符串的regexp字边界

时间:2017-09-06 00:59:40

标签: javascript regex

我已经看过关于这个主题的各种帖子,但找不到满意的答案

我需要一个正则表达式来匹配像#xxx#这样的字符串 - 这是一个字符串,可能在前面和后面有不是az AZ 0-9的字符 - 它在字边界内 - 前面和后跟^或$或不在az AZ 0-9

中的字符

我希望将此替换为不区分大小写和全局匹配,我正在寻找以下形式的解决方案:

#xxx的正则表达式#:

'#xxx#'.replace(regexp, 'bla') => 'bla'
'#xxx#,#xXx#)'.replace(regexp, 'bla') => 'bla,bla)'
'(#xXx#, #xxx#)'.replace(regexp, 'bla') => '(bla, bla)'

'a#xxx#'.replace(regexp, 'bla') => 'a#xxx#'
'#xXx#0'.replace(regexp, 'bla') => '#xXx#0'
'hello'.replace(regexp, 'bla') => 'hello'

xx的regexp:

'xxx'.replace(regexp, 'bla') => 'bla'
'xxx,xXx)'.replace(regexp, 'bla') => 'bla,bla)'
'(xXx, xxx),'.replace(regexp, 'bla') => '(bla, bla)'

'axxx'.replace(regexp, 'bla') => 'axxx'
'xXx0'.replace(regexp, 'bla') => 'xXx0'
'hello'.replace(regexp, 'bla') => 'hello'

我尝试了各种解决方案(即(?!\w)#xxx#(?!\w))但无法使其发挥作用。

基本上我正在寻找\ b,当字符串中有非alnum字符时,它会起作用。

任何帮助?

2 个答案:

答案 0 :(得分:1)

不确定我是否理解正确,但将模式限制为

  

之前和之后是^或$或不在a-z A-Z 0-9的字符

您可以使用/(^|[^0-9a-zA-Z])pattern goes here([^0-9a-zA-Z]|$)/

  • (^|[^0-9a-zA-Z])将匹配字符串的开头或不在0-9a-zA-Z中的字符;
  • 相似([^0-9a-zA-Z]|$)匹配字符串的结尾或不在0-9a-zA-Z中的字符;

测试用例

1)对于 #xxx#



var samples = ['#xxx#',
               '#xxx#)',
               '(#xxx#,',
               'a#xxx#',
               '#xxx#0',
               'hello']
               
console.log(
  samples.map(s => s.replace(/(^|[^0-9a-zA-Z])#xxx#([^0-9a-zA-Z]|$)/, '$1bla$2'))
)




2)对于 xxx



var samples = ['xxx',
               'xxx)',
               '(xxx,',
               'axxx',
               'xxx0', 
               'hello']
              
console.log(
  samples.map(s => s.replace(/(^|[^0-9a-zA-Z])xxx([^0-9a-zA-Z]|$)/, '$1bla$2'))
)




答案 1 :(得分:0)

我不确定正则表达式是否可行,我选择了这样的javascript解决方案:



const isAlnumChar = c => (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');

const replace = (s, f, r) => {
  const lcs = s.toLowerCase(), lcf = f.toLowerCase(), flen = f.length;
  let res = '', pos = 0, next = lcs.indexOf(lcf, pos);
  if (next === -1) return s;

  do {
    if ((next === 0 || !isAlnumChar(s[next - 1])) && (next + flen === s.length || !isAlnumChar(s[next + flen]))) {
      res += s.substring(pos, next) + r;
    } else {
      res += s.substring(pos, next + flen);
    }
    pos = next + flen;
  } while ((next = lcs.indexOf(lcf, pos)) !== -1);
  return res + s.substring(pos);
};


console.log(replace('#xxx#', '#xxx#', 'bla'));
console.log(replace('#xxx#,#xXx#)', '#xxx#', 'bla'));
console.log(replace('(#xXx#, #xxx#)', '#xxx#', 'bla'));

console.log(replace('a#xxx#', '#xxx#', 'bla'));
console.log(replace('#xXx#0', '#xxx#', 'bla'));
console.log(replace('hello', '#xxx#', 'bla'));

console.log(replace('xxx', 'xxx', 'bla'));
console.log(replace('xxx,xXx)', 'xxx', 'bla'));
console.log(replace('(xXx, xxx),', 'xxx', 'bla'));

console.log(replace('axxx', 'xxx', 'bla'));
console.log(replace('xXx0', 'xxx', 'bla'));
console.log(replace('hello', 'xxx', 'bla'));
&#13;
&#13;
&#13;