首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我很难编写这个函数,以便在<b></b>中包装(不区分大小写)子字符串的匹配,但保留匹配内容的大小写。

我很难编写这个函数,以便在<b></b>中包装(不区分大小写)子字符串的匹配,但保留匹配内容的大小写。
EN

Stack Overflow用户
提问于 2022-11-10 04:38:20
回答 1查看 24关注 0票数 0

我发现进行不区分大小写的匹配,但是用原始内容(而不是搜索的内容)的情况来替换匹配并不是那么简单。或者至少比类似的版本要复杂得多,在这种版本中,可以将匹配替换为子字符串。我该怎么做?我的应用程序应该是一个简单的部分,我已经花了太多的时间了。代码的测试用例应该澄清这个问题。

代码语言:javascript
复制
// Want to wrap instances of a substring (matching case-INsensitive)
// with <b> and </b>, but maintain the case-sensitivity of the source.

function regEscape(v) {
    return v.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}

function boldSubstring(source, substr) {
    const regx = new RegExp(regEscape(substr), "ig")
    const indices = [...source.matchAll(regx)].map(a => a.index)
    
    // filter: I actually don't know why these empty matches are 
    // happening; this is a patch. Might be wrong.
    const parts = source.split(regx).filter(part => part !== '')
    
    // Here we add our inserted parts.
    const updatedParts = parts.slice(0)
    let result
    for (let i = 0, j = 0; i < parts.length; i += 1, j += 2) {
        let joiner = '<b>' + source.slice(indices[i], indices[i] + substr.length) + '</b>'
        updatedParts.splice(j, 0, joiner)
    }
    return updatedParts.join('')
}

const searchStr1 = 't'

const tests1 = [
  {
    in: 'Default description.',
    out: 'Defaul<b>t</b> descrip<b>t</b>ion.'
  },
  {
    in: 'Tiger toe',
    out: '<b>T</b>iger <b>t</b>oe'
  },
  {
    in: 'TTiger ttoe',
    out: '<b>T</b><b>T</b>iger <b>t</b><b>t</b>oe'
  },
  {
    in: 'T1234',
    out: '<b>T</b>1234'
  },
  {
    in: 't1234',
    out: '<b>t</b>1234'
  },
]

const searchStr2 = 'ti'

const tests2 = [
  {
    in: 'Default description.',
    out: 'Default description.'
  },
  {
    in: 'Tiger toe',
    out: '<b>Ti</b>ger toe'
  },
  {
    in: 'TTiger ttoe',
    out: 'T<b>Ti</b>ger ttoe'
  },
  {
    in: 'T1234',
    out: 'T1234'
  },
  {
    in: 't1234',
    out: 't1234'
  },
]

function test(search, tests) {
  tests.forEach(testPair => {
    const result = boldSubstring(testPair.in, search)
    const passed = result === testPair.out
    if (passed) console.log('Passing:', result, '===', testPair.out)
    else console.log('Failing:', result, '!==', testPair.out)
  })
}

test(searchStr1, tests1)
test(searchStr2, tests2)

我打赌我想得太过分了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-10 04:48:55

假设Default description应该是第二个测试用例中的Default descrip<b>ti</b>on.,则可以通过使用.replace()使其更简单

代码语言:javascript
复制
source.replace(regx, "<b>$&</b>");

通过使用"<b>$&</b>"的替换参数,您可以告诉replace用封装在<b></b>标记中的匹配($&)替换正则表达式的所有匹配。

代码语言:javascript
复制
// Want to wrap instances of a substring (matching case-INsensitive)
// with <b> and </b>, but maintain the case-sensitivity of the source.

function regEscape(v) {
    return v.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}

function boldSubstring(source, substr) {
    const regx = new RegExp(regEscape(substr), "ig")
    return source.replace(regx, "<b>$&</b>");
}

const searchStr1 = 't';
const tests1 = [ { in: 'Default description.', out: 'Defaul<b>t</b> descrip<b>t</b>ion.' }, { in: 'Tiger toe', out: '<b>T</b>iger <b>t</b>oe' }, { in: 'TTiger ttoe', out: '<b>T</b><b>T</b>iger <b>t</b><b>t</b>oe' }, { in: 'T1234', out: '<b>T</b>1234' }, { in: 't1234', out: '<b>t</b>1234' }, ];

const searchStr2 = 'ti'
const tests2 = [ { in: 'Default description.', out: 'Default descrip<b>ti</b>on.' }, { in: 'Tiger toe', out: '<b>Ti</b>ger toe' }, { in: 'TTiger ttoe', out: 'T<b>Ti</b>ger ttoe' }, { in: 'T1234', out: 'T1234' }, { in: 't1234', out: 't1234' }, ];


function test(search, tests) {
  tests.forEach(testPair => {
    const result = boldSubstring(testPair.in, search)
    const passed = result === testPair.out
    if (passed) console.log('Passing:', result, '===', testPair.out)
    else console.log('Failing:', result, '!==', testPair.out)
  })
}

test(searchStr1, tests1);
test(searchStr2, tests2);

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74384217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档