使用多个分隔符进行剪切

问题描述 投票:0回答:3

我有一个小问题。我有一个包含以下内容的变量

CTI_VARIABLES

cti_CallDirection=1@;cti_ContractNumber=00202417@;cti_TransferVDN=48195@;cti_IvrButton=1

此变量中的每个不同变量都标记为“@;”相隔 .我试图用

CUT()
函数将它们分开。但它只返回第一个,因为它接受单个字符作为参数。当我想用两个字符分隔时该怎么办?

这是我的拨号方案代码

exten => addheader,1,NoOp(CTI_VARIABLES: ${CTI_VARIABLES})
same => n,GotoIf($["${CTI_VARIABLES}" = ""]?noVariables)
same => n,Set(TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,@\;)})
same => n,Set(COUNTER=1)
same => n,While($[${COUNTER} <= ${TOTAL_VARS}])
same => n,Set(CURRENT_VAR=${CUT(CTI_VARIABLES,@\;,${COUNTER})})
same => n,Set(VAR_NAME=${CUT(CURRENT_VAR,\=,1)})
same => n,Set(VAR_VALUE=${CUT(CURRENT_VAR,\=,2)})
same => n,Set(PJSIP_HEADER(add,${VAR_NAME})=${VAR_VALUE})
same => n,NoOp(${VAR_NAME}: ${VAR_VALUE})
same => n,Set(COUNTER=$[${COUNTER}+1])
same => n,EndWhile
same => n(noVariables),NoOp(No CTI Variables Set)

我也尝试使用

FIELDQTY()
功能,但没有成功:

TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,\@\;)}
TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,@;)}
asterisk
3个回答
1
投票

简单的答案是修复你的 AGI 以输出更有用的东西。 Asterisk 的 dialplan 语法对于执行任何实际的编程任务来说都是非常糟糕的,一个好的理念是避免在 dialplan 中做任何可以在其他地方做的事情。理想情况下,在这种情况下,您可以用值填充各个变量。

但如果这不是一个选项,那么只需在处理之前将

@;
序列替换为单个字符即可。

STRREPLACE(CTI_VARIABLES,@;,;)

现在您可以在分号上使用

CUT()

完整的diaplan(未经测试)

exten => addheader,1,NoOp(CTI_VARIABLES: ${CTI_VARIABLES})
same => n,GotoIf($["${CTI_VARIABLES}" = ""]?noVariables)
same => n,Set(CTI_VARIABLES=${STRREPLACE(CTI_VARIABLES,@;,;)})
same => n,Set(TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,;)})
same => n,Set(COUNTER=1)
same => n,While($[${COUNTER} <= ${TOTAL_VARS}])
same => n,Set(CURRENT_VAR=${CUT(CTI_VARIABLES,;,${COUNTER})})
same => n,Set(VAR_NAME=${CUT(CURRENT_VAR,=,1)})
same => n,Set(VAR_VALUE=${CUT(CURRENT_VAR,=,2)})
same => n,Set(PJSIP_HEADER(add,${VAR_NAME})=${VAR_VALUE})
same => n,NoOp(${VAR_NAME}: ${VAR_VALUE})
same => n,Set(COUNTER=$[${COUNTER}+1])
same => n,EndWhile
same => n(noVariables),NoOp(No CTI Variables Set)

请注意,除非处理逗号,否则不需要进行任何转义; Asterisk 的参数解析非常基础。


1
投票

为什么你可能需要数一些东西来完成这个简单的任务?

所以。让我给你“星号方式”:

; noop actually not needed, because MSet will show you all variables
exten => addheader,1,NoOp(CTI_VARIABLES: ${CTI_VARIABLES})

same => n,Set(MVAR=${STRREPLACE(CTI_VARIABLES,@;,\,)}); replace all @; to comma
same => n,MSet(${MVAR}); put all names/vars on channel
; actually if you know variable names, you not need all below
; same=>n,Dumpchan();uncomment this if you want to see result.

same => n(loop),ExecIf($[ "${MVAR}" == "" ]?Return()); exit
same => n,Set(VAR=${CUT(MVAR,\,,1)}); get next one
same => n,Set(MVAR=${CUT(MVAR,\,,2-)}); put from second back in string
; at this moment VAR has variable name and MVAR have other pairs without ${VAR}=${${VAR}}
same => n,Set(VAR_NAME=${CUT(VAR,=,1)}); get only name

same => n,Set(PJSIP_HEADER(add,${VAR_NAME})=${${VAR_NAME}); catch it from channel and put in header
same => n,Goto(loop); next one

仅此而已

简短提示为什么所有这些都有效。

MSet语法是这样的

[Syntax]
MSet(name1=value1[,name2=value2[,...]])

它将在一个命令中设置所有变量

如果您正在使用

 ${${VAR}}

星号将获取变量 VAR 的值并放入具有该名称的变量的值。

如果 cut 没有分隔符,并且您要求第二个参数,它将返回空字符串。

所以实际上完美的方法是以这样的格式从 CURL 请求或 AGI 或这些变量的任何来源返回您需要的所有信息

cti_CallDirection=1,cti_ContractNumber=00202417,cti_TransferVDN=48195,cti_IvrButton=1

之后制作单个 MSet 并为标头放置可读的拨号计划。


-1
投票

您似乎正在尝试在拨号方案代码中使用 CUT 函数来划分 CTI_VARIABLES 字符串中的变量。但您遇到的问题是您有一个两个字符的分隔符“@;”,但 CUT 只允许一个字符作为分隔符。 REGEX 函数在 CURRENT_VAR=${REGEX(${CTI_VARIABLES},([^@;]+)@;,,${COUNTER})} 行中使用,使用正则表达式模式 ([^@ ;]+)@;。该模式记录一个或多个非“@”或“;”字符,然后在它们后面加上“@;”。通过使用 REGEX 函数中的 ${COUNTER} 选项,在 while 循环中一次提取一个变量。 使用与之前相同的代码设置变量名称、变量值并将它们添加为 PJSIP 标头。

© www.soinside.com 2019 - 2024. All rights reserved.