简体   繁体   English

根据第一个字符或字符的先前出现限制模式的一部分

[英]Restrict part of pattern based on first character or previous occurance of character

I have the following regexp: 我有以下正则表达式:

/^(?:(?:>|<)?[a-zA-Z]+(?:(?:\+|-)\d*\.?\d*(?:em)?)?)(?:<[a-zA-Z]+(?:(?:\+|-)\d*\.?\d*(?:em)?)?)?$/

Which you can think about like this: 您可以这样考虑:

^
  (?:
    (?:>|<)?
    [a-zA-Z]+
    (?:(?:\+|-)\d*\.?\d*(?:em)?)?
  )
  (?:
    <
    [a-zA-Z]+
    (?:(?:\+|-)\d*\.?\d*(?:em)?)?
  )?
$

It is effectively the same pattern repeated once or twice with a small difference. 它实际上是相同的模式,重复一次或两次,差异很小。 The core of each pattern is one or more letter [a-zA-Z] followed by an optional minus or plus and a numeric value possibly followed by em . 每个模式的核心是一个或多个字母[a-zA-Z]后跟可选的减号或加号,以及可能跟em的数字值。 The first instance can start with either < or > and the second instance can only start with < . 第一个实例可以以<>开头,第二个实例只能以<开头。

So the following are all valid: 因此,以下所有内容均有效:

  `alpha`,
  `alphaBravo`,
  `alphaBravoCharlie`,
  `>alpha`,
  `<alpha`,
  `>alpha+10`,
  `<alpha+10`,
  `>alpha+1.5`,
  `<alpha+1.5`,
  `>alpha-10`,
  `>alpha-10`,
  `>alpha-1.5`,
  `>alpha-1.5`,
  `>alpha+10em`,
  `<alpha+10em`,
  `>alpha+1.5em`,
  `<alpha+1.5em`,
  `>alpha-1.5em`,
  `>alpha-1.5em`,
  `alpha-50em<delta-100em`,
  `alpha-50em<delta+100em`,
  `>alpha-50em<delta+100em`,

My problem is that if the first instance starts with a < then the second instance shouldn't be allowed, so the following should be invalid: 我的问题是,如果第一个实例以<开头,则不应允许第二个实例,因此以下内容应无效:

<alpha<bravo

Is it possible to add this restriction to the regexp? 是否可以将此限制添加到正则表达式?

The two approaches I can think of are: 我能想到的两种方法是:

  1. Check the first character and make the second instance invalid if it is < 检查第一个字符,如果第二个实例<
  2. Check if < has already ocurred in the string (or if < occurs again in the string) and if so, make the second instance invalid. 检查<已在字符串中已经内容时发生(或者,如果<字符串中再次发生),如果是这样,请二审无效。

However I'm not sure how to implement either of these approaches here. 但是,我不确定如何在此处实现这两种方法。

You could use a very early negative lookahead right after caret ^ : 您可以在插入符号^之后使用非常早的否定性超前查询:

(?!<[^<\s]*<)

Live demo 现场演示

You also don't need to use alternations to match a single character at a time ie (?:>|<) should be [<>] or (?:\\+|-) should be [+-] . 您也不需要一次使用替换来匹配单个字符,即(?:>|<)应该为[<>](?:\\+|-)应该为[+-]

Extended mode: 扩展模式:

^
  (?!<[^<\s]*<) # We have this extra one
  (?:
    [<>]?
    [a-zA-Z]+
    (?:[-+]\d+(?:\.\d+)?(?:em)?)?
  )
  (?:
    <
    [a-zA-Z]+
    (?:[-+]\d+(?:\.\d+)?(?:em)?)?
  )?
$

In a line: 在一行中:

^(?!<[^<\s]*<)(?:[<>]?[a-zA-Z]+(?:[-+]\d+(?:\.\d+)?(?:em)?)?)(?:<[a-zA-Z]+(?:[-+]\d+(?:\.\d+)?(?:em)?)?)?$

Just replace (?:(?:>|<)? with (?:(?:>|<(?!.*<))? to get desired results. 只需将(?:(?:>|<)?替换为(?:(?:>|<(?!.*<))?即可获得所需的结果。

Test it here . 在这里测试。


If you want to extend this feature from < character to > character as well, you can replace same part of the pattern (?:(?:>|<)? with (?:([<>])(?!.*\\1))? and replace <? with [<>]? in the second part of your pattern. 如果还要将此功能从<字符扩展到>字符,则可以将模式的相同部分(?:(?:>|<)?替换为(?:([<>])(?!.*\\1))?然后在模式第二部分将<?替换为[<>]?

Test it here . 在这里测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM