技术细节
我想从包含参数名称和值的文本文件中提取值。对于以"request.config"开头的每一行。(有空行,带注释的行等,我不想从中提取任何内容)我想提取这些值(粗体):
request.config。 my_param_1 = "一些随机字符串",
我认为最好的方法来做到这一点可能是使用REGEX,但我怎么能做到这一点?
我认为应该有一个类似正则表达式的东西,它可以提取2个值request.config.${1} = ${2};
,并为每行检索${1}和${2},但只有在匹配的情况下。
我试了试,但没有成功:
<cfset str = "request.config.MY_PARAM_NAME = 'The parameter VALUE!!';">
<cfset arrSearch = rematch("^request.config.(.*?) = (.*?);$", str) >
<cfdump var="#arrSearch#" label="Extracted values">
不幸的是,这段代码给了我一个完整的字符串,我已经有了,我只想要两个提取的值!
Some META: WHAT I'm trying to do
我正在构建一个web应用程序,允许最终用户修改存储在params_file.cfm中的一些应用程序参数。而不是让开发人员在文件中手动更改变量,我们希望能够在应用程序中完成。
我的应用程序首先对后端进行AJAX调用,后端读取params文件,获取所有数据对(param_name, param_value和可能稍后的param_description),并将它们作为JSON返回以填充我的列表,我有一个自动完成工具,可以按名称搜索它们(Typeahead.js)。当我选择一个参数名称时,该值将与一些控件一起出现,以修改它们(控件取决于数据类型,使用JQuery来确定类型)。
问题是param_value可以有多种形式。因为这个参数文件是由不同的人维护的,所以它可以有不同的语法。例如,一个布尔值可以存储为"TRUE","TRUE","TRUE","TRUE","TRUE"(你懂的)。
由于SerializeJSON处理类型(布尔值,数字,字符串),我认为我的REGEX应该返回给我没有引号的文本(单引号或双引号),但我在制作该表达式时遇到了麻烦。
I got
<cfset match = REFind("^request.config.(S+) = ['|""]?(.*)['|""]?;$", str, 1, "Yes")>
,我用request.config.my_param_1 = 'MYTEST123';
测试了它,它只删除第一个单引号,由于某种原因,表达式返回我MYTEST123'
时,我不想要任何周围的引号。我需要帮助我的REGEX
你不想要REMatch
,你想要REFind
(docs):
REFind(reg_expression, string [, start, returnsubexpressions ] )
returnsubexpressions
是你需要的,所以…
<cfset str = "request.config.MY_PARAM_NAME = 'The parameter VALUE!!';">
<cfset match = REFind("^request.config.(S+) = (.*);", str, 1, "Yes")>
<cfdump var="#match#">
match
将是一个具有两个键(POS
和LEN
)的Struct,列出每个子匹配的位置和长度。
然后您可以将此信息提供给Mid()
并删除实际的子字符串。
不要忘记检查REFind
是否成功,ArrayLen(match.POS)
在你的情况下必须是3(1个整体匹配,两个匹配组,认为$0
..$2
)。
要查找整个文件中出现的所有内容,请执行
- 在循环中运行此函数,将
start
设置为match.POS[1] + match.LEN[1]
用于下一次迭代 - 或逐行循环文件,通过
<cfloop list>
以换行符Chr(10)
作为分隔符,或通过<cfloop array>
和ArrayToList(file, Chr(10))
。
您需要尝试refind(),而不是rematch(),因为它返回可用于获取和查找子表达式的数组数据
arrsearch = rematch("^request.config.(.*?) = (.*?);$", line)
返回整行:#Mid(line,arrsearch.pos[0],arrsearch.len[0])#
返回第一个子表达式(varname):#Mid(line,arrsearch.pos[1],arrsearch.len[1])#
返回第二个子表达式(value):#Mid(line,arrsearch.pos[2],arrsearch.len[2])#