24

我是正则表达式的新手,这可能是一个非常简单的问题(希望如此)。

我正在尝试对 3 种字符串使用一种解决方案

  • “45%”,预期结果:“45”
  • “45”,预期结果:“45”
  • ““, 预期结果: ””

我正在尝试什么(让字符串为str):

str.match(/(.*)(?!%*)/i)[1]

这在我的脑海中听起来就像“匹配任何实例直到 '%' 如果找到它,或者只是匹配任何东西”

在萤火虫的脑海中,这听起来更像是“只匹配任何东西,完全忽略负前瞻”。也让它变得懒惰 - (.*)?- 似乎没有帮助。

让我们暂时忘记,在这种特定情况下,我只匹配数字,所以 a/\d*/会这样做。我试图理解一个一般规则,以便我可以随时应用它。

有人会这么好心来帮助我吗?

4

5 回答 5

39

更简单的怎么样

str.match(/[^%]*/i)[0]

这意味着,匹配零个或多个字符,而不是%.


编辑:如果需要解析 until </a>,那么您可以解析一个序列 pf 字符,然后是</a>,然后丢弃</a>,这意味着您应该使用正面预测而不是负面预测。

str.match(/.*?(?=<\/a>|$)/i)[0]

这意味着:懒惰地匹配零个或多个字符,直到到达</a>字符串的一个或结尾。

注意*?是单操作符,(.*)?不一样.*?

(并且不要像往常一样使用单个 regex 解析 HTML。)

于 2011-12-21T03:23:51.317 回答
9

我想这就是你要找的:

/(?:(?!%).)*/

.匹配任何字符,但仅在否定前瞻之后,(?!%)确认字符不是%。请注意,当哨兵是单个字符时%,您可以使用否定字符类代替,例如:

/[^%]*/

但是对于像这样的多字符哨兵</a>,您必须使用前瞻方法:

/(?:(?!</a>).)*/i

这实际上是说“一次匹配零个或多个字符,但如果下一个字符是序列的开头</a>or </A>,则停止而不消耗它”。

于 2011-12-21T04:46:24.047 回答
3

使用精确搜索字符串的最简单方法是跳过正则表达式并仅使用indexOf,例如:

// String to be searched
var s = "Here is a <a>link</a>."

// String to find
var searchString = "</a>";

// Final match
var matched = "";

var c = s.indexOf(searchString);
if (c >= 0)
{
    // Returns the portion not including the search string;
    // in this example, "Here is a <a>link". If you want the
    // search string included, add the length of the search
    // string to c.
    matched = s.substring(c);
}
于 2011-12-21T03:44:48.833 回答
1

我只是按照你的说法写的:

str.match(/(^[^%]*$)|^([^%]*)%.*/i)

这将匹配任何没有 '%' 的字符串或包含 % 的字符串的第一部分。您必须从第一组或第二组中获得结果。

编辑:这正是你想要的

str.match(/(?:^[^%]*$)|^(?:[^%]*)(?=%)/)
  • ?: 删除所有分组
  • ?= 是先行查看字符串是否包含 %
  • 并且 [^%] 匹配任何不是 % 的字符

所以正则表达式读取匹配任何不包含 % 的字符串,或者(否则匹配)第一个 % 之前的所有字符

于 2011-12-21T03:40:23.273 回答
0

要匹配 45、45% 和任意长度的任意数量,请使用此(182%、18242 等)

str.match(/([0-9]+)([%]?)/)[1];

如果您需要匹配空字符串也将其包含为^$,请注意 match("...")[1]将未定义空字符串,因此您需要测试匹配然后检查 [0] 或查看 [1] 是否未定义。

str.match(/([0-9]+)([%]?)|^$/)

如果您需要精确匹配两个数字,请使用{2,2}锚定开始和结束行字符之间的表达式:“ ^ (exp) $

str.match(/^([0-9]{2,2})([%]?)$/)[1];
于 2011-12-21T04:21:40.027 回答