【问题标题】:RegEx - Match Only Strings That Have a Dollar Sign At Their BeginningRegEx - 仅匹配开头有美元符号的字符串
【发布时间】:2018-08-06 22:02:29
【问题描述】:

我已经尝试了几个小时来完成此任务,但我仍处于学习 RegEx 的初期,因此请向这里的专家寻求帮助。 如何仅匹配开头有美元符号的字符串? 我已经用这个正则表达式取得了部分成功:

(?<=\$)\[(?=[^\]]*[a-z])([a-zA-Z_]+[\w]+)\]

在这个代码块上:

<?php
$options[$list[_capture_me]][]=array($list[_captureme],$list[_capture_me]);
      $option_names[$list[_capture_me]]=$list[_captureme];
      $product_name=$list[capture_me];
$product_name=$list[0];
$product_name=$list[DONTCAPTUREME];
$product_name=$list[CapTureMe];
$product_name=$list[CapTurEME];
            $actionKey = $get[DONT_CAPTURE_ME];

        if(array_key_exists(DONT_CAPTURE_ME,$get)) {
            $actionKey = $get[DONT_CAPTURE_ME];
            if(array_key_exists($actionKey,$this->arrPageActions)){
                    $this->arrAllTemplatesAndAttributes[$templateID][captureme]['Capture_Me'][$res[option_values_id]] = $res[DONT_CAPTURE_ME];
$old_faq_id.="$result[faq_id]&";    
      $result['toc']="<b><a href=$PHP_SELF#$result[faq_id]>$result['question']</a></b>";}
 $result['toc']="<b><a href=$PHP_SELF#$result[faq_id]>$result[QUESTION]</a></b>";}
$login_groups_id = $check_admin[login_groups_id];
?>

<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->

function check_input(field_name, field_size, message) {
  if ($elements[capture_me] && (form.elements[dont_capture].type != "hidden") && $form.elements[capture_me]) {
    var field_value = form.elements[dontcapture].value;
  var field_value = $form.elements[captureme].value;

    if (field_value == '' || field_value.length < field_size) {
      error_message = error_message + "* " + message + "\n";
      error = true;
    }
  }
}

正如您在DEMO 中看到的那样,它也匹配括号内的字符串,即使它们的开头没有美元符号,我需要防止这种情况发生。 我尝试像这样添加积极的lookbehind:

(?<=\$\w+)

但这在这个引擎中不起作用,错误:

lookbehind 中的量词使其宽度不固定

有什么办法可以做到吗?

顺便说一句,我这样做是因为我的最终目标是使用替换为括号中的所有字符串添加单引号,因此像这样的行 $product_name=$list[CapTureMe]; 将变为 $product_name=$list['CapTureMe'];,例如,使用以下代码:

['\1']

DEMO #2

谢谢

【问题讨论】:

  • regex101.com/r/5OeJSw/1 喜欢这个?
  • 哇。看起来不错,但它仍然不匹配 $form.elements[capture_me] 例如
  • 这甚至是有效的 PHP 语法吗?我以为. 是字符串连接。
  • 你是对的,它根本不是有效的 php 或 js,只是我正在测试的东西。请发表你的答案,让我以某种方式感谢你:)
  • Regex 不是解析复杂语言的工具。 PHP 有一个tokenizer,使用它。

标签: regex search replace pcre


【解决方案1】:

在简单的情况下你可以使用

(\$\w+)\[(\w*[a-z]\w*)\]

作为你的正则表达式和

$1['$2']

作为替代品。

详细的正则表达式:

  • \$\w+ 匹配 $ 符号,后跟 1 个或多个单词字符(字母、数字、下划线)
  • ( ) 捕获匹配的字符串(#1)
  • \[ 匹配文字 [
  • \w*[a-z]\w* 匹配 0 个或多个单词字符,后跟一个小写字母,后跟 0 个或多个单词字符(即,我们匹配的单词在某处至少包含一个小写字母)
  • ( ) 捕获匹配的字符串(#2)
  • \] 匹配文字 ]

我们将其替换为

  • $1 - 第一个捕获缓冲区的内容
  • [' - 两个字符 ['
  • $2 - 第二个捕获缓冲区的内容
  • '] - 两个字符 ']

如果需要,您可以变得更花哨(这很快就会失控):

((?:\$|->)\w+)\[(\w*[a-z]\w*)\]

还允许在开头使用-&gt; 而不是$。这将匹配例如-&gt;bar[baz]$foo-&gt;bar[baz].

另一个可能的补充可能是

((?:\$|->)\w+(?:\[\$\w+\])*)\[(\w*[a-z]\w*)\]

(?:\[\$\w+\])* 部分允许在初始标识符和末尾未加引号的单词之间有 0 个或多个带括号的变量名称。这将匹配例如$foo[$bar][$baz][quux]$1 中的$foo[$bar][$baz]$2 中的quux)。

但是,这些解决方案都不能同时匹配$foo[bar][baz] 中的barbaz。这是一项非常重要的任务,因为它需要重叠匹配。

【讨论】:

  • 非常感谢。有什么办法让它也匹配$foo[bar][baz]这样的案例吗?我在问题中的正则表达式确实如此。这样它就会找到并将其转换为$foo['bar']['baz']
  • @CM웃 我猜你可以做类似(?:\$\w+|\])\[\K(\w*[a-z]\w*)(?=\])(替换为'$1')(使用\K 模拟可变宽度后视),但这并不能真正验证匹配时,它只查找变量$foo],然后是一些未引用的索引[foo]
  • 我正在考虑的另一个选项是使用问题中的正则表达式并向其添加多行检查以查看代码是否为 php 代码,即。如果它仅在&lt;?php?&gt; 之间,否则它将失败。任何建议如何结合我的正则表达式来实现此检查?
  • @CM웃 我可以构建这种方法(和我的正则表达式)失败的各种场景。如果您想转换任意代码,我会使用实际的解析器(或至少标记器)。如果你把整个事情都塞进一个正则表达式中,那你的日子就不好过了。
猜你喜欢
  • 1970-01-01
  • 2019-08-06
  • 2010-10-24
  • 1970-01-01
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
相关资源
最近更新 更多