【问题标题】:Javascript regular expression: match anything up until something (if there it exists)Javascript正则表达式:匹配任何东西直到某物(如果存在)
【发布时间】:2012-01-24 23:06:03
【问题描述】:

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

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

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

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

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

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

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

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

有人愿意帮我吗?

【问题讨论】:

  • 否定的前瞻:(?!%*) 说:“断言不遵循零个或多个百分号” 这个断言永远不会是真的,因为%* 总是真的! (%* 根本不匹配 - 这总是 在任何地方都是正确的 - 即使对于空字符串也是如此。)

标签: javascript regex regex-lookarounds


【解决方案1】:

更简单的怎么样

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

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


编辑:如果需要解析到</a>,那么你可以解析一个序列pf字符,后跟</a>,然后丢弃</a>,这意味着你应该使用positive 前瞻而非否定。

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

这意味着:惰性匹配零个或多个字符,直到到达&lt;/a&gt; 或字符串结尾。

注意*?是单个运算符,(.*)?.*?不同。

(和往常一样,don't parse HTML with a single regex。)

【讨论】:

  • 在正则表达式中,尤其是 JavaScript 风格中,^character 表示从引用字符串的开头开始匹配。 developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
  • @austincheney:当^ 被用作文本锚时这是正确的,但^ 在字符类中使用时具有不同的含义,即它否定匹配(“除了这些字符...")。
  • 谢谢肯尼,这行得通。但是如果“%”是“”呢?我想排除一个模式而不是一个字符。为了更清楚起见,“”(或任何模式)可能存在也可能不存在。
  • 谢谢肯尼,这正是我希望找到的。请参阅我对艾伦的评论。我也非常感谢你花时间一点一点地解释它......圣诞快乐!
【解决方案2】:

我想这就是你要找的东西:

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

. 匹配任何字符,但只有在否定前瞻 (?!%) 确认该字符不是 % 之后。请注意,当标记是% 这样的单个字符时,您可以使用否定字符类来代替,例如:

/[^%]*/

但是对于像&lt;/a&gt; 这样的多字符标记,您必须使用前瞻方法:

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

这实际上是说“一次匹配零个或多个字符,但如果下一个字符是&lt;/a&gt;&lt;/A&gt; 序列的开头,则停止而不使用它”。

【讨论】:

  • 这很棒。正是我想要的。感谢你和肯尼,现在我知道如何一步一步地确保我的最后一步不会落在某个模式/((?!pattern).)*/ 以及如何走很长一段路直到下一个字符是我的模式的开始,或者字符串/.*?(?=pattern|$)/ 的结尾。我认为肯尼的更符合我的期望,而你的则不那么明显,而且绝对出色。我不认为我会想到它。谢谢!
【解决方案3】:

exact 搜索字符串最简单的方法是跳过正则表达式,只使用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);
}

【讨论】:

  • 谢谢 bobby,但我一直在寻找 RegEx 解决方案。你所描述的是我通常会做的,但这样做我最终会重申我的这个小词汇..
【解决方案4】:

我只是照你说的写了:

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

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

编辑:这正是你想要的下面

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

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

【讨论】:

    【解决方案5】:

    要匹配 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];
    

    【讨论】:

      猜你喜欢
      • 2020-10-13
      • 1970-01-01
      • 2022-12-23
      • 2012-11-12
      • 2011-10-28
      • 1970-01-01
      • 2016-10-19
      • 2016-03-04
      相关资源
      最近更新 更多