SAS 程序冷知識(shí)——關(guān)于%quote系函數(shù)中%的轉(zhuǎn)義問題

上一篇是關(guān)于%str和%nrstr兩個(gè)函數(shù)的SAS 程序冷知識(shí)——一個(gè)關(guān)于%str和%nrstr的案例解讀 - 簡書

此處是上次的一個(gè)擴(kuò)展。同樣具有mask效果的quote一族是怎樣處理%的呢别凹?對(duì)于quote一族來說锣险,%當(dāng)然也具有兩個(gè)功能垄开,一個(gè)是宏的觸發(fā)符號(hào)答渔,一個(gè)是mask關(guān)鍵詞的功能养涮。

首先是bquote鸭丛,這個(gè)函數(shù)的作用是mask所有特殊符號(hào)后频,所以在這函數(shù)里%不具備任何特殊符號(hào)的作用梳庆,所以不必用兩個(gè)%mask暖途。

有趣的是quote和nrquote,我們先看代碼:

%let s1=%%@2個(gè)百分號(hào);

%let s2=%%%%@4個(gè)百分號(hào);

%let s3=%%%%%%%%@8個(gè)百分號(hào);

%let s4=%%%%%%%%%%%%%%%%@16個(gè)百分號(hào);

%macro a(quote=,nrquote=);

%put &=quote.;

%put &=nrquote.;

%mend;

%a(quote=%quote(&s1.),nrquote=%nrquote(&s1.));

%a(quote=%quote(&s2.),nrquote=%nrquote(&s2.));

%a(quote=%quote(&s3.),nrquote=%nrquote(&s3.));

%a(quote=%quote(&s4.),nrquote=%nrquote(&s4.));

結(jié)果是:

QUOTE=%@2個(gè)百分號(hào)

NRQUOTE=%@2個(gè)百分號(hào)

QUOTE=%@4個(gè)百分號(hào)

NRQUOTE=%%@4個(gè)百分號(hào)

QUOTE=%%@8個(gè)百分號(hào)

NRQUOTE=%%%%@8個(gè)百分號(hào)

QUOTE=%%%%@16個(gè)百分號(hào)

NRQUOTE=%%%%%%%%@16個(gè)百分號(hào)

我們發(fā)現(xiàn)對(duì)于nrquote來說膏执,經(jīng)過該函數(shù)%的個(gè)數(shù)都減半了驻售。這個(gè)可以理解為:對(duì)于每對(duì)%而言,前一個(gè)%作為mask的符號(hào)更米,轉(zhuǎn)義了后一個(gè)%的特殊作用欺栗,然后前一個(gè)%完成使命消失,從而最后的個(gè)數(shù)是原來的一半征峦。

但是quote就有意思了迟几,在4個(gè)百分號(hào)的時(shí)候,結(jié)果依然是一個(gè)%眶痰,并且按照后面的規(guī)則看瘤旨,似乎quote在執(zhí)行了第一遍轉(zhuǎn)義之后,又進(jìn)行了一次轉(zhuǎn)義竖伯。

然后如果宏是這樣的:

%macro b(quote=,nrquote=);

%put quote=%quote(&quote.);

%put nrquote=%nrquote(&nrquote.);

%mend;

%b(quote=&s1.,nrquote=&s1.);

%b(quote=&s2.,nrquote=&s2.);

%b(quote=&s3.,nrquote=&s3.);

%b(quote=&s4.,nrquote=&s4.);

結(jié)果就完全不一樣存哲,變得正常了。

quote=% 2個(gè)百分號(hào)

nrquote=% 2個(gè)百分號(hào)

quote=%% 4個(gè)百分號(hào)

nrquote=%% 4個(gè)百分號(hào)

quote=%%%% 8個(gè)百分號(hào)

nrquote=%%%% 8個(gè)百分號(hào)

quote=%%%%%%%% 16個(gè)百分號(hào)

nrquote=%%%%%%%% 16個(gè)百分號(hào)

這個(gè)結(jié)果表明七婴,如果在宏變量賦值的時(shí)候祟偷,就帶著函數(shù)quote,那么當(dāng)使用的時(shí)候%會(huì)被作為轉(zhuǎn)義符執(zhí)行兩次打厘。為了驗(yàn)證這個(gè)結(jié)論我們?cè)僮鲆淮卧囼?yàn)修肠。

%let s1=%quote(%%@2個(gè)百分號(hào));

%let s2=%quote(%%%%@4個(gè)百分號(hào));

%let s3=%quote(%%%%%%%%@8個(gè)百分號(hào));

%let s4=%quote(%%%%%%%%%%%%%%%%@16個(gè)百分號(hào));

%put quote=&s1.;

%put quote=&s2.;

%put quote=&s3.;

%put quote=&s4.;

其結(jié)果為:

quote=%@2個(gè)百分號(hào)

quote=%@4個(gè)百分號(hào)

quote=%%@8個(gè)百分號(hào)

quote=%%%%@16個(gè)百分號(hào)

這個(gè)結(jié)果基本驗(yàn)證了我們的想法。那么為什么quote就會(huì)執(zhí)行兩次呢户盯?猜想原因是宏變量賦值的時(shí)候嵌施,是先執(zhí)行宏函數(shù),后賦值莽鸭。我們以%let s3=%quote(%%%%%%%%@8個(gè)百分號(hào));為例吗伤。當(dāng)賦值的時(shí)候,s3的值可以%%%%@8個(gè)百分號(hào)硫眨。而當(dāng)我們使用語句:%put quote=&s3.;的時(shí)候足淆,由于解析宏變量中帶有%quote的功能,所以在解析后再次執(zhí)行轉(zhuǎn)義功能礁阁,從而產(chǎn)生的結(jié)果”%%@8個(gè)百分號(hào)”巧号。詳見:SAS 程序冷知識(shí)——一個(gè)關(guān)于%str和%nrstr的案例解讀(續(xù)) - 簡書?

那么為什么nrquote就不會(huì)有問題呢?我們通過試驗(yàn)看到了quote的運(yùn)行機(jī)制姥闭。quote和nrquote實(shí)際上本質(zhì)是在字符的兩端加上一個(gè)標(biāo)志符號(hào)丹鸿,這個(gè)符號(hào)往往我們無法直接通過put看到,但是如果用16進(jìn)制解析就能清楚看到棚品,我們顯示示例如下:

%let s1=%%%%%%%%@8個(gè)百分號(hào);

%let s2=%quote(%%%%%%%%@8個(gè)百分號(hào));

%let s3=%nrquote(%%%%%%%%@8個(gè)百分號(hào));

data _null_;

set sashelp.vmacro;

where name='S1';

S1=strip(value);

put S1= hex50.;

run;

data _null_;

set sashelp.vmacro;

where name='S2';

S2=strip(value);

put S2= hex50.;

run;

data _null_;

set sashelp.vmacro;

where name='S3';

S3=strip(value);

put S3= hex50.;

run;

執(zhí)行之后可以看到

S1中25有8個(gè)卜高,實(shí)際上是符號(hào)‘%’弥姻,到了S2中25變成了4個(gè),這說明quote已經(jīng)轉(zhuǎn)義掉了其中的4個(gè)掺涛。但是S2的前后各多了一個(gè)符號(hào),分別是03和08(20表示空格疼进,是長度不夠補(bǔ)位用的)薪缆。其他的位置,S1和S2完全一樣伞广,對(duì)應(yīng)的就是文字“@8個(gè)百分號(hào)”拣帽。

到了S3就更有趣了,和S2內(nèi)容一樣嚼锄,但區(qū)別在于開頭的符號(hào)從03變成了05减拭,然后百分號(hào)從25變成了10。

這樣我們就大致理解quote和nrquote的操作了区丑,當(dāng)使用這個(gè)函數(shù)的時(shí)候拧粪,首先函數(shù)會(huì)在字符兩端加上兩個(gè)符號(hào),結(jié)尾都是08沧侥,quote的開頭是03可霎,nrquote的開頭是05。一旦套上的是05宴杀,SAS會(huì)進(jìn)一步將原來的%和&轉(zhuǎn)換成其他符號(hào)癣朗,來達(dá)到mask宏觸發(fā)符號(hào)的目的。因此我們猜測執(zhí)行順序是這樣的:

1旺罢、解析quote或nrquote中的宏變量旷余。

2、兩端加上mask符號(hào)08扁达,03或05正卧。

3、有%的話進(jìn)行轉(zhuǎn)義罩驻,將+穗酥,-等符號(hào)進(jìn)行替換。

4惠遏、如果是nrquote砾跃,將%和&進(jìn)行符號(hào)替換。

5节吮、如果是quote抽高,檢查是否有%可以執(zhí)行。

而之所以nrquote不會(huì)執(zhí)行2次透绩,是因?yàn)樵诘谝淮螆?zhí)行轉(zhuǎn)義之后翘骂,所有的%就都被替換成其他字符了壁熄,因此也就不會(huì)又后面的轉(zhuǎn)義了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碳竟,一起剝皮案震驚了整個(gè)濱河市草丧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌莹桅,老刑警劉巖昌执,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诈泼,居然都是意外死亡懂拾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門铐达,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岖赋,“玉大人,你說我怎么就攤上這事瓮孙√贫希” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵衷畦,是天一觀的道長栗涂。 經(jīng)常有香客問我,道長祈争,這世上最難降的妖魔是什么斤程? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮菩混,結(jié)果婚禮上忿墅,老公的妹妹穿的比我還像新娘。我一直安慰自己沮峡,他們只是感情好疚脐,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著邢疙,像睡著了一般棍弄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疟游,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天呼畸,我揣著相機(jī)與錄音,去河邊找鬼颁虐。 笑死蛮原,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的另绩。 我是一名探鬼主播儒陨,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼花嘶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹦漠?” 一聲冷哼從身側(cè)響起椭员,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笛园,沒想到半個(gè)月后拆撼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喘沿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竭贩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚜印。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖留量,靈堂內(nèi)的尸體忽然破棺而出窄赋,到底是詐尸還是另有隱情,我是刑警寧澤楼熄,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布忆绰,位于F島的核電站,受9級(jí)特大地震影響可岂,放射性物質(zhì)發(fā)生泄漏错敢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一缕粹、第九天 我趴在偏房一處隱蔽的房頂上張望稚茅。 院中可真熱鬧,春花似錦平斩、人聲如沸亚享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽欺税。三九已至,卻和暖如春揭璃,著一層夾襖步出監(jiān)牢的瞬間晚凿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工塘辅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晃虫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓扣墩,卻偏偏與公主長得像哲银,于是被迫代替她去往敵國和親扛吞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容