文章目录

  • 第十四章 Caché 函数大全 $EXTRACT 函数
  • ​大纲​



第十四章 Caché 函数大全 $EXTRACT 函数

按位置从字符串中提取子字符串,或按位置替换子字符串。

大纲

$EXTRACT(string,from,to)
$E(string,from,to)

SET $EXTRACT(string,from,to)=value
SET $E(string,from,to)=value

参数

  • string 标识子字符串的目标字符串。将字符串指定为计算结果为带引号的字符串或数字值的表达式。在​​SET $EXTRACT​​语法中,字符串必须是变量或多维属性。
  • from 可选-指定目标字符串中的起始位置。字符从1开始计算。允许的值为n(一个正整数,指定从字符串开头的字符计数),​​*​​​(指定字符串中的最后一个字符)和​​* -n​​​(从字符串末尾向后偏移的字符整数)。​​SET $EXTRACT​​​语法还支持​​* + n​​(附加在字符串末尾的偏移量整数字符)。从(不含)到的值指定单个字符。从到的从指定字符范围。如果未指定from,则默认为1。
  • to 可选-指定字符范围的结束位置(含)。必须与from一起使用。允许的值为n(指定从字符串开头开始的字符计数的正整数),​​*​​​(指定字符串中的最后一个字符)和​​* -n​​​(从字符串末尾向后偏移的字符整数)。​​SET $EXTRACT​​​语法还支持​​* + n​​(要追加到字符串末尾的字符范围的末尾的偏移整数计数)。

描述

​$EXTRACT​​通过字符串计数(从字符串的开头或字符串的结尾)识别字符串中的子字符串。子字符串可以是单个字符或字符范围。

​$EXTRACT​​可以以两种方式使用:

  • 从字符串返回子字符串。这使用​​$EXTRACT(string,from,to)​​语法。
  • 替换字符串中的子字符串。替换子字符串的长度可以与原始子字符串相同,更长或更短。这使用 ​​SET $EXTRACT(string,from,to)=value​​语法。

返回子字符串

​$EXTRACT​​按字符串中的字符位置返回子字符串。该子字符串提取的性质取决于使用的参数。

  • ​$Extract(String)​​提取字符串中的第一个字符。
DHC-APP>SET mystr="ABCD"

DHC-APP>WRITE $EXTRACT(mystr)
A
  • ​$Extract(string,from)​​在from指定的位置提取单个字符。From值可以是从字符串开头开始的整数计数,可以是指定字符串最后一个字符的星号,也可以是具有指定从字符串末尾向后计数的负整数的星号。

以下示例从字符串“​​ABCD​​”中提取单个字母:

DHC-APP>SET mystr="ABCD"

DHC-APP>WRITE !,$EXTRACT(mystr,2)

B
DHC-APP>WRITE !,$EXTRACT(mystr,*)

D
DHC-APP>WRITE !,$EXTRACT(mystr,*-2)

B
DHC-APP>WRITE !,$EXTRACT(mystr,*-0)

D
  • ​$EXTRACT(string,from,to)​​​提取从from位置开始到to位置(包括)的字符范围。例如,如果变量​​var2​​​包含字符串“​​1234Alabama567​​​”,则以下​​$EXTRACT​​​函数都将返回字符串“​​Alabama​​”:
DHC-APP>SET var2="1234Alabama567"

DHC-APP> WRITE !,$EXTRACT(var2,5,11)

Alabama
DHC-APP>WRITE !,$EXTRACT(var2,*-9,*-3)

Alabama

参数

string

标识子字符串的目标字符串。

当使用​​$EXTRACT​​​返回子字符串时,字符串可以是用引号引起来的字符串文字,规范的数字,变量,对象属性或任何求值为字符串或数字的有效ObjectScript表达式。如果将空字符串(​​“”​​​)指定为目标字符串,则​​$EXTRACT​​始终返回该空字符串,而不考虑其他参数值。

当​​$EXTRACT​​​与等号左侧的​​SET​​一起使用以替换子字符串时,string可以是变量名或多维属性引用;它不能是非多维对象属性。

from

from参数可以指定单个字符或字符范围的开头。

  • 如果from为​​n​​​(正整数),则​​$EXTRACT​​从字符串的开头开始计算字符。
  • 如果from是​​*​​​(星号),则​​$EXTRACT​​返回字符串中的最后一个字符。
  • 如果from是​​* -n​​​(一个星号后跟一个负数),则​​$EXTRACT​​​将从字符串末尾开始的偏移量计算字符。因此,​​*-0​​​是字符串中的最后一个字符,​​*-1​​是字符串中的倒数第二个字符(从末尾偏移1)。
  • 仅适用于​​SET $EXTRACT​​​语法—如果from是​​* + n​​​(星号后跟一个正数),则​​SET $EXTRACT​​​会在字符串的末尾附加偏移量。因此,​​* + 1​​​在字符串末尾附加一个字符,​​* + 2​​​在字符串末尾两个位置附加一个字符,将跳过的位置用空格填充。 ​​* + 0​​是字符串中的最后一个字符。

如果from整数值大于字符串中的字符数,则​​$EXTRACT​​​返回空字符串。使用从​​* -n​​​的值,如果​​n​​​等于或大于字符串中的字符数,则​​$EXTRACT​​​返回空字符串。如果from值为0或负数,则​​$EXTRACT​​返回空字符串;但是,如果将from与to一起使用,则from值0或负数将被视为1值。

如果将from与to参数一起使用,则from标识要提取的范围的开始,并且必须小于to的值。如果从等于等于,则​​$EXTRACT​​​返回指定位置的单个字符。如果from大于to,则​​$EXTRACT​​返回一个空字符串。如果与to参数一起使用,则from值小于1(零或负数)将被视为数字1。

to

to参数必须与from参数一起使用。它必须是正整数,​​*​​​(星号)或​​* -n​​​(星号后跟负整数)。如果to值是大于或等于from值的整数,则​​$EXTRACT​​​返回指定的子字符串。如果to值为星号,则​​$EXTRACT​​​返回子字符串,该子字符串以from字符开始,直至字符串的末尾。如果to是大于字符串长度的整数,则​​$EXTRACT​​还将返回子字符串,该子字符串以from字符开始,直到字符串的末尾。

如果from和to位置相同,则​​$EXTRACT​​​返回单个字符。如果to位置比from位置更接近字符串的开头,则​​$EXTRACT​​返回空字符串。

如果省略to参数,则仅返回一个字符。如果指定了from,则​​$EXTRACT​​​返回由from标识的字符。如果同时省略了to和from,则​​$EXTRACT​​返回字符串的第一个字符。

仅适用于​​SET $EXTRACT​​​语法—如果to为​​* + n​​​,​​SET $EXTRACT​​​会在字符串的末尾附加偏移量的字符范围,并根据需要用空格填充。如果from表示字符串末尾的字符位置,则​​SET $EXTRACT​​​将附加字符。如果from表示字符串末尾之前的字符位置,则​​SET $EXTRACT​​可以替换和附加字符。

指定* -n和* + n参数值

使用变量指定​​* -n​​​或​​* + n​​时,必须始终在参数本身中指定星号和符号字符。

以下是​​* -n​​的有效格式:

DHC-APP>SET count=2

DHC-APP>SET alph="abcd"

DHC-APP>WRITE $EXTRACT(alph,*-count)
b
DHC-APP>SET count=2

DHC-APP>SET alph="abcd"

DHC-APP>WRITE $EXTRACT(alph,*+count)

以下是​​* +n​​的有效格式:

DHC-APP>SET count=2

DHC-APP>SET alph="abcd"

DHC-APP>SET $EXTRACT(alph,*+count)="F"

DHC-APP>WRITE alph
abcd F

这些参数值内允许使用空格。

示例:返回子字符串

以下示例返回“​​D​​”,即字符串中的第四个字符:

DHC-APP>SET x="ABCDEFGHIJK"

DHC-APP>WRITE $EXTRACT(x,4)
D

以下示例返回“​​K​​”,即字符串中的最后一个字符:

DHC-APP>SET x="ABCDEFGHIJK"

DHC-APP>WRITE $EXTRACT(x,*)
K

在下面的示例中,所有​​$EXTRACT​​​函数都将“​​J​​”返回字符串中的倒数第二个字符:

DHC-APP>SET n=-1

DHC-APP>SET m=1

DHC-APP>SET x="ABCDEFGHIJK"

DHC-APP>WRITE !,$EXTRACT(x,*-1)

J
DHC-APP>WRITE !,$EXTRACT(x,*-m)

J
DHC-APP>WRITE !,$EXTRACT(x,*+n)

J
DHC-APP>WRITE !,$EXTRACT(x,*-1,*-1)

J

请注意,星号和整数变量之间需要减号或加号。

下面的示例显示当from值为“​​1​​​”时,一参数格式等效于二参数格式。 ​​$EXTRACT​​​函数都返回“​​H​​”。

DHC-APP>SET x="HELLO"

DHC-APP>WRITE !,$EXTRACT(x)

H
DHC-APP>WRITE !,$EXTRACT(x,1)

H

下面的示例返回一个子字符串“​​THIS IS​​”,它由第一到第七个字符组成。

DHC-APP>SET x="THIS IS A TEST"

DHC-APP>WRITE $EXTRACT(x,1,7)
THIS IS

以下示例还返回子字符串“​​THIS IS​​​”。当from变量的值小于1时,​​$EXTRACT​​将该值视为1。因此,以下示例返回由第一到第七个字符组成的子字符串。

DHC-APP>SET X="THIS IS A TEST"

DHC-APP>WRITE $EXTRACT(X,-1,7)
THIS IS

下面的示例返回字符串的最后四个字符:

DHC-APP>SET X="THIS IS A TEST"

DHC-APP>WRITE $EXTRACT(X,*-3,*)
TEST

以下示例还返回字符串的最后四个字符:

DHC-APP>SET X="THIS IS A TEST"

DHC-APP>WRITE $EXTRACT(X,*-3,14)
TEST

下面的示例从对象属性中提取一个子字符串:

DHC-APP>SET tStatement = ##class(%SQL.Statement).%New()

DHC-APP>SET tStatement.%SchemaPath="MyTests,Sample,Cinema"

DHC-APP> WRITE "whole schema path: ",tStatement.%SchemaPath,!
whole schema path: MyTests,Sample,Cinema

DHC-APP>WRITE "start of schema path: ",$EXTRACT(tStatement.%SchemaPath,1,10),!
start of schema path: MyTests,Sa

使用SET $EXTRACT替换子字符串

可以将​​$EXTRACT​​​与​​SET​​命令一起使用,以另一个值替换指定的字符或字符范围。也可以使用它在字符串末尾附加字符。

当​​$EXTRACT​​​与等号左侧的​​SET​​​一起使用时,字符串可以是有效的变量名。如果该变量不存在,则​​SET $EXTRACT​​​对其进行定义。字符串参数也可以是多维属性引用。它不能是非多维对象属性。尝试在非多维对象属性上使用​​SET$EXTRACT​​​会导致​​<Object Dispatch>​​错误。

如果函数使用相对偏移量语法:​​*​​​表示字符串末尾,而​​*-n​​​或​​*+n​​​表示相对于字符串末尾的相对偏移量,则不能将​​set(a,b,c,...)=Value​​​语法与等号左侧的​​$EXTRACT(或$PICEL或$LIST)​​​一起使用。必须改用​​set a=value、b=value、c=value、...​​。语法。

​SET $EXTRACT​​的最简单形式是一对一替换:

DHC-APP>SET alph="ABZD"

DHC-APP>SET $EXTRACT(alph,3)="C"

DHC-APP>WRITE alph
ABCD

通过将to指定为比字符串长度大1的正整数,或将to指定为​​*+1​​,可以将字符附加到字符串,如下例所示:

DHC-APP>SET alph="ABCD"

DHC-APP>SET $EXTRACT(alph,5)="E"

DHC-APP>WRITE alph ; "ABCDE"
ABCDE
DHC-APP>SET alph="ABCD"

DHC-APP>SET $EXTRACT(alph,*+1)="E"

DHC-APP>WRITE alph ; "ABCDE"
ABCDE

如果指定大于字符串加1的值,则​​$EXTRACT​​填充空格为空白:

DHC-APP>SET alph="ABCD"

DHC-APP>SET len=$LENGTH(alph)

DHC-APP>SET $EXTRACT(alph,len+2)="F"

DHC-APP>WRITE alph
ABCD F
DHC-APP>SET alph="ABCD"

DHC-APP>SET $EXTRACT(alph,*+2)="F"

DHC-APP>WRITE alph
ABCD F

还可以提取一个字符串,并将其替换为其他长度的字符串。例如,以下命令从​​foo​​​中提取字符串“​​Rhode Island​​​”,并将其替换为字符串“ ​​Texas​​”,而无需填充。

DHC-APP>SET foo="Deep in the heart of Rhode Island"

DHC-APP>SET $EXTRACT(foo,22,33)="Texas"

DHC-APP>WRITE foo
Deep in the heart of Texas

可以提取字符串并将其设置为空字符串,然后从字符串中删除提取的字符:

DHC-APP>SET alph="ABCzzzzzD"

DHC-APP>SET $EXTRACT(alph,4,8)=""

DHC-APP>WRITE alph
ABCD

如果指定从大于到,则不会发生替换:

DHC-APP>SET alph="ABCD"

DHC-APP>SET $EXTRACT(alph,4,3)="X"

DHC-APP>WRITE alph
ABCD

在下面的示例中,假定变量​​x​​不存在。

DHC-APP>KILL x

DHC-APP>SET $EXTRACT(x,1,4)="ABCD"

DHC-APP>WRITE x
ABCD

​SET​​​命令创建变量​​x​​​并为其分配值“​​ABCD​​”。

​SET $EXTRACT​​​将根据需要使用空格填充前导填充,但不执行尾部填充。下面的示例在字符串末尾的第六个位置插入值“​​F​​”,但在位置7和8处不插入其他字符:

DHC-APP>SET alph="ABCD"

DHC-APP>SET $EXTRACT(alph,6,8)="F"

DHC-APP>WRITE alph
ABCD F

下面的示例在第六个位置插入值“​​F​​”,并添加超出指定范围的字符:

DHC-APP>SET alph="ABCD"

DHC-APP>SET $EXTRACT(alph,6,8)="FGHIJ"

DHC-APP>WRITE alph
ABCD FGHIJ

下面的示例通过将from提取到大于替换字符串中的值数目的范围来缩短字符串。

DHC-APP>SET $EXTRACT(x,3,6)="Z"

DHC-APP>WRITE x
ABZGH

在第三个位置插入值“​​Z​​​”,并删除位置4、5和6。变量x现在包含值“​​ABZGH​​”,长度为5。

注意

$EXTRACT和Unicode

​$EXTRACT​​​函数对字符而不是字节进行操作。因此,Unicode字符串的处理方式与ASCII字符串相同,如以下示例所示,将Unicode字符用作“​​pi​​​”(​​$ CHAR(960)​​):

/// d ##class(PHA.TEST.Function).EXTRACT()
ClassMethod EXTRACT()
{
IF $SYSTEM.Version.IsUnicode() {
SET a="QT PIE"
SET b="QT "_$CHAR(960)
SET a1=$EXTRACT(a,-33,4)
SET a2=$EXTRACT(a,4,4)
SET a3=$EXTRACT(a,4,99)
SET b1=$EXTRACT(b,-33,4)
SET b2=$EXTRACT(b,4,4)
SET b3=$EXTRACT(b,4,99)
WRITE !,"ASCII form returns ",!,a1,!,a2,!,a3
WRITE !,"Unicode form returns ",!,b1,!,b2,!,b3
} ELSE {
WRITE "This example requires a Unicode installation of Caché"
}
}
ASCII form returns
QT P
P
PIE
Unicode form returns
QT π
π
π

代理对

​$EXTRACT​​​无法识别代理对。代理对用于表示某些中文字符并支持日语JIS2004标准。可以使用​​$WISWIDE​​​函数确定字符串是否包含代理对。 ​​$WEXTRACT​​​函数可以识别并正确解析代理对。 ​​$EXTRACT​​​和​​$EXTRACT​​​相同。但是,由于​​$EXTRACT​​​通常比​​$WEXTRACT​​​快,因此对于不可能遇到代理对的所有情况,​​$EXTRACT​​是更可取的。

DTM模式下的$EXTRACT

在DTM和DTM-J模式下,​​$EXTRACT​​支持两个附加参数,如下所示:

$EXTRACT(string,from,to,replace,pad)

可选的replace参数用replace子字符串替换from和to指定的子字符串,并返回结果。原始字符串不变。

可选的pad参数指定填充字符。当from参数指定一个超出字符串末尾的位置时,将使用此选项。返回的字符串将填充到from所指定的位置,后跟replace子字符串。填充值可以是任何单个字符;非数字字符必须用引号引起来。要将引号字符指定为填充字符文字,请将其加倍。

可以使用​​%SYSTEM.Process​​​类的​​LanguageMode()​​方法来设置DTM模式(2)或DTM-J模式(7)。

以下示例显示了四参数替换语法:

DHC-APP>SET x="ABCDEFGH"

DHC-APP>DO ##class(%SYSTEM.Process).LanguageMode(2)

DHC-APP>WRITE $EXTRACT(x,3,6,"##")
AB##GH

以下示例使用四参数语法附加替换字符串:

DHC-APP>SET x="ABCDEFGH"

DHC-APP> DO ##class(%SYSTEM.Process).LanguageMode(2)

DHC-APP>WRITE $EXTRACT(x,1,0,"##")
##ABCDEFGH

以下示例显示了五参数填充和替换语法:

DHC-APP>SET x="ABCDEFGH"

DHC-APP> DO ##class(%SYSTEM.Process).LanguageMode(2)

DHC-APP>WRITE $EXTRACT(x,12,16,"##","*")
ABCDEFGH***##

注意:使用四参数或五参数语法时,​​$EXTRACT​​​ from和to参数不支持星号语法。 ​​SET $EXTRACT​​不能与四参数或五参数语法一起使用。

EXTRACT与PIECE和$LIST的比较

​$EXTRACT​​​通过从字符串开头计数字符来确定子字符串。 ​​$EXTRACT​​​将任何普通字符串作为输入。 ​​$PIECE​​​和​​$LIST都​​可用于特殊准备的字符串。

​$PIECE​​通过计算字符串中用户定义的定界符来确定子字符串。

​$LIST​​通过从列表的开头计数元素(而非字符)来确定编码列表中的元素。 ​​$LIST​​不能用于普通字符串,而​​$EXTRACT​​不能用于编码列表。