【问题标题】:Regex with optional dots in a alphanumeric string字母数字字符串中带有可选点的正则表达式
【发布时间】:2021-02-27 09:41:54
【问题描述】:

我正在尝试编写一个与可能包含点的固定字母数字字符串匹配的正则表达式。
此正则表达式必须匹配除点之外的所有字符。 我需要在 Javascript search() 中使用它来比较两个字符串。 要查找的单词:30A10Z20

所有这些都是正确的匹配:

30A1.0Z2.0
30A.10Z20
3.0.A10.Z20
3.0.A.1.0.Z.2.0.

我已经写了这些,但没有成功:

^30A10Z20\\.{0,1}?$
^30A10Z20\\.?$
^30A10Z20(?=\\.)

非常感谢任何线索或帮助。

【问题讨论】:

  • 如果你只是替换所有的点然后检查字符串是否等于30A10Z20会更容易。
  • @Sweeper 是对的,否则你必须放 \.?在每个字符之后...
  • 30A...............10Z20 也有效吗?
  • @georg 是的,有效
  • @Sweeper 我想过,但这对我不利。 30A10Z20 只是最终字符串的一部分(例如“30A10Z20 Lorem Ipsum 3324”),我必须匹配我提到的内容,以便可以使用 html 标签(粗体)对其进行格式化。它必须包含它们所在的点。

标签: javascript regex alphanumeric


【解决方案1】:

我不确定RegExp 是否是完成我认为您想做的事情的最佳方式(基于您的 cmets:尝试重新制定您的问题)。这个 sn-p 会是一个主意吗?

const findTerm = (word, searchTerm) => 
  word.replace(/[^a-z0-9]/gi, "") === searchTerm;

const aFewStrings = [
  `something 30A1.0Z2.0 etc`,
  `30A.10Z20 hithere`,
  `Hello 3.0.A10.Z20`,
  `The value 3.0.....A.1.0....Z.2.0. may be valid`,
  `As may be the value 3.0@@@A.1.0#&!'Z.2.0.`,
  `Bye 3.0.A.1.0.Z.2.0. ended`,
];

aFewStrings.forEach(s => {
  const words = s.split(" ").map( w => findTerm(w, "30A10Z20") ? `<b>${w}</b>` : w );
  console.log(words.join(" "));
});

如果您想要部分字符串(参见您的评论),您必须进行一些解析。比如:

const findTerm = (word, searchTerm) =>
  RegExp(`(${searchTerm})`, "i").test(word.replace(/[^a-z0-9]/gi, ""));

const toBold = (word, searchTerm) => {
  const word2Parse = [...word];
  const wordPreserved = word2Parse.slice(0);
  const len = searchTerm.length;
  let foundIndices = [];
  let i = 0;

  while (word2Parse.length) {
    const noDots = word2Parse.slice(1).filter(v => !/[^a-z0-9]/i.test(v));
    const next = searchTerm.length > 1 &&  noDots[0] === searchTerm[1];
    const found = searchTerm.length > 1 
        ? word2Parse[0] === searchTerm[0] && next
        : word2Parse[0] === searchTerm[0];
    
    searchTerm = found ? searchTerm.slice(1) : searchTerm;
    found && foundIndices.push(i);
    i += 1;
    word2Parse.shift();
  }


  wordPreserved[foundIndices[0]] = `<b>${wordPreserved[foundIndices[0]]}`;
  wordPreserved[foundIndices.slice(-1)] = `${
        wordPreserved[foundIndices.slice(-1)]}</b>`;
  return wordPreserved.join("");
}

const aFewStrings = [
  `something 30A1.0Z2.0 etc`,
  `30A.10Z20 hithere`,
  `Hello 3.0.A10.Z20`,
  `The value 3.0.....A.1.0....Z.2.0. may be valid`,
  `As may be the value 3.0@@@A.1.0#&!'Z.2.0.`,
  `Bye 3.0.A.1.0.Z.2.0. ended`,
  `3.0.A.1.0.Z.2.....0`,
];


const result = document.querySelector("#result");

let term = `30A1`;
result.appendChild(
  Object.assign(
    document.createElement("p"), {
      innerHTML: `[1 String, search '30A1']: ${
          (aFewStrings[3].split(" ")
            .map(w =>
                findTerm(w, term) ? toBold(w, term) : w)
            .join(" "))}`
    })
);

term = `notfound`;
result.appendChild(
  Object.assign(
    document.createElement("p"), {
      innerHTML: `[1 String, search 'notfound']: ${
          (aFewStrings[1].split(" ")
            .map(w =>
                findTerm(w, term) ? toBold(w, term) : w)
            .join(" "))}`
    })
);

term = `0Z20`;
aFewStrings.forEach(s => {
  const words = s.split(" ").map(w =>
    findTerm(w, term) ? toBold(w, term) : w);
  result.appendChild(
    Object.assign(
      document.createElement("div"), {
        innerHTML: words.join(" ")
      })
  );
});
body {
  margin: 2rem;
  font: normal 12px/15px verdana, arial;
}

b {
  color: red;
}
&lt;div id="result"&gt;&lt;/div&gt;

【讨论】:

  • 这很有效,非常好。但是有没有办法让它只与字符串的一部分一起工作?例如"30A1" --> 30.A10Z.20 或 "Z20" --> 30.A.10Z20
  • 我想是可以做到的,但是确实比较复杂。您可能需要考虑简化输入(因此,首先要确保点不存在)
  • 我可以删除输入上的点并进行比较。但后来我需要一种方法,将文本格式加粗显示在我最初找到的内容上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多