Regex 正则表达式匹配所有字符,但限制某些字符

Regex 正则表达式匹配所有字符,但限制某些字符,regex,Regex,我有php代码,它要求搜索词,将其拆分,并生成一个正则表达式来匹配(并突出显示)模式。例如: 如果我输入ou,它将生成以下模式:(o)(.*)(u)。然后将其替换为$1$2$3。 在以下数据中 boau #fie diu1^^j dauijz16 abc123 wwx,usq 这将产生以下效果: b<strong>o</strong>au #fie diu1^^j dauijz16 abc123 wwx,<strong>u</strong>sq

我有php代码,它要求搜索词,将其拆分,并生成一个正则表达式来匹配(并突出显示)模式。例如:
如果我输入
ou
,它将生成以下模式:
(o)(.*)(u)
。然后将其替换为
$1$2$3
。 在以下数据中

boau #fie diu1^^j dauijz16 abc123 wwx,usq
这将产生以下效果:

b<strong>o</strong>au #fie diu1^^j dauijz16 abc123 wwx,<strong>u</strong>sq
或者,不允许使用任何数字:

b<strong>o</strong>au #fie di<strong>u</strong>1^j dauijz16 abc123 wwx,usq
boau#fie diu1^j dauijz16 abc123 wwx,usq

因此,我希望能够输入要搜索的模式,并为某些字符指定单独的限制,但我不知道如何做到这一点。我认为这与前瞻性有关,但我不知道如何使用它们。

您在这里问了很多问题

我将回答一个看起来最复杂的问题,即如果我将空格限制为3,则回答:

您可以使用此正则表达式:

$s = 'boau #fie diu1^^j dauijz16 abc123 wwx,usq';
$r = preg_replace('/(o)((?:[^ ]* ){0,3}[^ u]*)(u)/', "<em>$1</em>$2<em>$3</em>", $s);
//=> b<em>o</em>au #fie diu1^^j da<em>u</em>ijz16 abc123 wwx,usq

此输出与您的预期结果相匹配。我希望您可以使用相同的方法,为问题的其他部分构建正则表达式。

为了限制空格的数量,我将使用:

(o)((?:\S*\s){0,3}\S*)(u)
下面是一个使用它的perl脚本:

my $re = qr/(o)((?:\S*\s){0,3}\S*)(u)/;
my $str = 'boau #fie d iu1^^j dauij z16 abc123 wwx,usq';
$str =~ s!$re!<em>$1</em>$2<em>$3</em>!;
say $str;

您可以使用否定类:

(o)((?:[^ ]* ){0,3}[^ ]*)(u)
限制在3个空间

没有数字<代码>\D匹配除数字以外的任何字符。请注意,它相当于被否定的类:
[^\d]

第二项要求比上述两项要求复杂得多:

(o)([^ ^]*(?:(\^)|( ))?[^ ^]*(?(3) |(?:( )|(\^)))?[^ ^]*(?(6) |(?:( )|(\^)))?[^ ^]*(?(8) |\^)?[^ ^]*)(u)
它尝试匹配一个
^
或一个空格,并根据捕获的内容决定是否可以匹配另一个空格或插入符号或不匹配

此正则表达式使用条件组,这不是所有正则表达式引擎都支持的。

正如您所见,一个限制非常简单,但多个限制很快就会失控。如果您有多个条件,例如,在伪代码中,我建议使用状态机:

match first character "o"
substring = "o"

statecaret = 0
statespace = 0

for (check next character)
    if character == "^"
        statecaret = statecaret + 1
    else if character == " "
        statespace = statespace + 1

    if (statecaret = 2 || statespace = 4)
        break and reject character
    else
        add character to substring

find last "u" in substring

同意,在这种情况下,
{0,3}
应该如您所示使用。我将您的正则表达式稍微更改为
(o)((?:[^]*\s[^]*){0,3}[^]*)(u)
,这非常适合极限空间要求。我尝试了一些方法来增加对其他角色的限制,但都不起作用。似乎我对正则表达式了解得不够。。你能帮我按顺序添加更多需求吗?当然我能帮你。请告诉我您的哪些需求需要我的帮助?假设我希望有以下限制:[最多2个空格;3到8个#符号;最多1\]我需要能够使用php生成此项。我不是要php代码,而是要一个可以按顺序构建的正则表达式,这需要前瞻性。因此,对于您的查询,您可以使用:
(?=(\S*\S){0,2}\S*$)(?=([^#]*\35;){3,8}[^#]*$)(?=[^\]*\][^\]*$)
*?
也匹配一个空格,因此整个正则表达式实际上匹配其中的4个空格,而不是3个。另外,我如何为其他角色添加限制?我试过一些方法,但都不管用。@DaJF:用
\S*
替换
*?
。请参阅我的编辑。好的,但其他要求如何?或者,您可以依次使用多个正则表达式来逐个提取字符串片段,最后进行替换。但我还是觉得你没有regex会更好。
b<em>o</em>au #fie d i<em>u</em>1^^j dauij z16 abc123 wwx,usq
The regular expression:

(?-imsx:(o)((?:\S*\s){0,3}.*?)(u))

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    o                        'o'
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
  (                        group and capture to \2:
----------------------------------------------------------------------
    (?:                      group, but do not capture (between 0 and
                             3 times (matching the most amount
                             possible)):
----------------------------------------------------------------------
      \S*                      non-whitespace (all but \n, \r, \t,
                               \f, and " ") (0 or more times
                               (matching the most amount possible))
----------------------------------------------------------------------
      \s                       whitespace (\n, \r, \t, \f, and " ")
----------------------------------------------------------------------
    ){0,3}                   end of grouping
----------------------------------------------------------------------
    \S*                      non-whitespace (all but \n, \r, \t, \f,
                             and " ") (0 or more times (matching the
                             most amount possible))
----------------------------------------------------------------------
  )                        end of \2
----------------------------------------------------------------------
  (                        group and capture to \3:
----------------------------------------------------------------------
    u                        'u'
----------------------------------------------------------------------
  )                        end of \3
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------
(o)((?:[^ ]* ){0,3}[^ ]*)(u)
(o)(\D*)(u)
(o)([^ ^]*(?:(\^)|( ))?[^ ^]*(?(3) |(?:( )|(\^)))?[^ ^]*(?(6) |(?:( )|(\^)))?[^ ^]*(?(8) |\^)?[^ ^]*)(u)
match first character "o"
substring = "o"

statecaret = 0
statespace = 0

for (check next character)
    if character == "^"
        statecaret = statecaret + 1
    else if character == " "
        statespace = statespace + 1

    if (statecaret = 2 || statespace = 4)
        break and reject character
    else
        add character to substring

find last "u" in substring