【问题标题】:CF Regex REFind() substring without quotesCF 正则表达式 REFind() 不带引号的子字符串
【发布时间】:2014-05-12 20:11:41
【问题描述】:

我的 CF 后端必须像读取 TEXT 文件一样读取 CFM 文件以提取不同参数的名称和值,数据如下所示:

request.config.MY_PARAM_1 = 'ABCDEFGHI';
request.config.MY_PARAM_2 = "BlaBlaBla";
request.config.MY_PARAM_3 = TRUE;
request.config.MY_PARAM_4 = 'true';
request.config.MY_PARAM_5 = "1337";
request.config.MY_PARAM_6 = 1337;

如您所见,我可以有可以单引号或双引号的字符串。

我也有 BOOLEANS 和 NUMBERS,它们通常不带引号,但也可以有(单引号或双引号)。

我正在“解析”文件并提取值,我想找到一个返回匹配项的模式:

request.config.MY_PARAM_2 = "BlaBlaBla";

我非常接近成功,但不幸的是,以下表达式无法摆脱​​结束引号。

<cfset match = REFind("^request\.config\.(\S+) = ['|""]?(.*)['|""]?;$", str, 1, "Yes")>
<cfset paramVal = Mid( str, match.pos[3], match.len[3] ) >
<cfdump var=#paramVal# >

例如,它返回BlaBlaBla",它已经成功省略了开头的引号,但不是最后一个,我做错了什么?

【问题讨论】:

  • 我想知道是否更容易改为在每一行前附加一个字符串,然后执行代码,从而用这些值填充一个本地结构。你不是已经问过这个了吗?
  • 不确定你的意思@KevinB,我确实想填充一个本地结构,在发送之前我将 SerializeJSON,问题是我当前的实现,结果将是例如: "\"1337\"",因为 SerializeJSON 认为它是一个字符串而不是一个数字。用我的正则表达式去掉引号可以解决所有这些烦恼,SerializeJSON 会重新添加引号,知道它是一个字符串,并且不会为布尔值和数字重新添加引号
  • 您可以通过遍历值并将值强制为数字或布尔值(如果它们是数字或布尔值)来解决这个问题。我只是不喜欢为此使用正则表达式的想法,它很容易破坏。
  • 例如,要解决您的问题,您需要匹配 (.*) 直到最后匹配的引号/apos。这可以通过多种方式解决,但都不是万无一失的。
  • 基本上,定义一个结构,variables.config = {};,查找/替换将request.config替换为variables.config,将文件保存到ram://,包含它,删除文件,然后访问variables.config 的属性。然后,您可以遍历这些属性,将字符串数字和字符串布尔值转换为数字和布尔值。当然,如果您不信任构建此配置文件的人,这会引入一个可能有人插入恶意代码的地方。

标签: regex coldfusion text-extraction data-extraction


【解决方案1】:

从您的 cmets 看来,您好像是在说要解析两行 ARBITRARY 行。这样就可以了:

^(?:[^\n]*\n){1}request\.config.(\w+)\s*=\s*(['"]?)(\w+)\2;(?:[^\n]*\n){4}request\.config.(\w+)\s*=\s*(['"]?)(\w+)\5;

在您的代码中,只需更改量词中的两个数字:{1}{4},因为它们指定要在顶部和中间跳过多少行。例如,对于第 1 行,您将在第一个量词中包含 {0}

您要的数据在Groups 1、3、4和5中。请查看this demo右下方面板中的捕获组

我相信通过连接各个部分在代码中构建正则表达式不会有任何问题:

method Parse(x,y)
Build the regex by concatenating
^(?:[^\n]*\n){
With 
x-1
With
}request\.config.(\w+)\s*=\s*(['"]?)(\w+)\2;(?:[^\n]*\n){
With
y-x
With
}request\.config.(\w+)\s*=\s*(['"]?)(\w+)\5;

Then match and retrieve Groups 1, 3, 4 and 5

还可以看到这个非常清晰的可视化。

Debuggex Demo

【讨论】:

  • 我想从 2 个匹配项中提取值,对于第一个示例,它将是:MY_PARAM_1ABCDEFGHI 但没有引号。对于示例 #5,它将是:MY_PARAM_51337。有我的要求
  • @dominicbri7 你能解释一下是什么让 MY_PARAM_1 和 MY_PARAM_5 如此特别吗?意思是,我怎么知道匹配那些而不是另一个?是关于报价吗?或者关于它们在参数列表中的位置(一个是第一个,另一个是第五个)?
  • @domonicbri7 如果您说您想要特定的第 1 行和第 5 行,请参阅我的答案顶部的附加正则表达式。如果不是,请解释我们使用什么标准来知道选择哪两条线。 :)
  • 我只给出了 #1 和 #5 作为示例,我正在寻找一个可以返回这些结果的 REGExpression
  • @domonicbri7 我刚刚添加了一个表达式,可以让您捕获两条任意行。这是我的答案的顶部。 :)
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2010-09-13
  • 2016-08-08
  • 2013-02-09
  • 2016-07-29
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多