1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        用SketchUp替換文本內(nèi)容

        共 6899字,需瀏覽 14分鐘

         ·

        2021-12-31 11:24


        SketchUp 中的 ruby 控制臺作為自動化操作的利器,自然也可以進(jìn)行最基本的文檔內(nèi)容修改任務(wù)。因此本篇使用 SketchUp 自帶的 ruby 控制臺制作一個文本文檔的替換小工具。


        編程無疑是將自己從重復(fù)性工作中解放出來的好辦法,但是對于完全的新手來說,某些編程工具在安裝這一步就相當(dāng)讓人迷惑,以至于一開始就勸退很多人。就像在Windows中,誰都可以直接使用一些MS-DOS批處理指令或VBS腳本,對于安裝了 SketchUp 的用戶來說,ruby 控制臺也是一個拿來即用的編程工具?;蛟S SketchUp 里的 ruby 只是一個簡陋的版本,但這的確節(jié)省了不少在安裝編程環(huán)境上的時間。


        *這是“SketchUp不務(wù)正業(yè)系列”中的一篇,文中淺紫色文字為“不務(wù)正業(yè)”對“正業(yè)”的借鑒參考。


        【本期目錄】

        一、替換文本的流程

        二、正則表達(dá)式

        三、代碼實現(xiàn)

        這是一個極其簡單的功能,幾乎完全不需要自己設(shè)計任務(wù)邏輯。




        一、替換文本的流程


        文本替換的流程是這樣的:

        ①確定原文件的路徑、替換文本的規(guī)則以及結(jié)果保存路徑;

        ②讀取文件內(nèi)容;

        ③根據(jù)設(shè)置的規(guī)則替換內(nèi)容;

        ④將替換后的內(nèi)容保存到新的文件中。


        新舊文件路徑的選擇可以使用最原始的輸入地址的方法,但是對于文件路徑比較復(fù)雜的情況來說,直接在窗口中選擇文件還是要方便一些。因此這一步需要使用 SketchUp 提供的打開和保存文件的對話框:

        filename=UI.openpanel("title")#>>?filename為選擇的文件名#???如果取消filename則為nil


        執(zhí)行以上代碼可以打開系統(tǒng)默認(rèn)的“打開”對話框,窗口的標(biāo)題可以自己更改:


        保存路徑的選擇也類似于“打開”對話框

        filename=UI.savepanel("title")#>>?filename為選擇的文件名


        二者的區(qū)別在于“保存”對話框可以設(shè)置新文件,且選擇已有的文件會有覆蓋警告;而“打開”對話框只能選擇存在的文件。


        確定了文件路徑后是讀取文件,可以使用以下代碼:

        str1=File.read(input_filename)#正常運行后str1將保存文件中的所有內(nèi)容#類型為String


        將字符串保存到新的文件中,則需要使用如下的代碼:

        f=File.open(filename,"w")f.write(str2)f.close()


        以上代碼中:第1行?.open 方法表示創(chuàng)建文件,其中的第二個參數(shù)?"w" 表示允許覆蓋創(chuàng)建。第2行的?.write 方法表示將?str2 寫入文件中,第3行的?.close 方法保存文件。


        最后是文本替換部分,這本是一個很復(fù)雜的任務(wù)邏輯,但是ruby有自帶的方法能夠?qū)崿F(xiàn)這個功能,唯一要做的就是了解字符串類的?.gsub 方法:

        str2?=?str1.gsub(op,np)


        簡單來說,這個方法就是以參數(shù)規(guī)定的規(guī)則替換?str1?中的特定內(nèi)容,然后將結(jié)果返回給?str2。如果兩個參數(shù)都是字符串,那么規(guī)則就是將文本中所有?op 替換成 np。如果參數(shù)?op 是正則表達(dá)式,那么替換的規(guī)則將更加復(fù)雜且靈活。


        二、正則表達(dá)式


        關(guān)于正則表達(dá)式,這里只提供一些感性的例子,詳細(xì)的語法規(guī)則和使用方法不是本篇文章能夠概括的??梢詤⒖家韵聝蓚€網(wǎng)址:

        • https://ruby-doc.org/core-2.7.1/String.html#method-i-gsub

        • https://www.runoob.com/regexp/regexp-tutorial.html


        (1)?簡易替換


        這種用法和系統(tǒng)自帶的記事本替換功能沒有區(qū)別,但是需要規(guī)避某些有特殊含義的符號:

        圖中的?"\xe7\x94\xa8\xe5\x9c\xb0" 表示“用地”,這么寫是因為 ruby 控制臺的輸入不是 UTF-8 編碼,所以會出現(xiàn)編碼錯誤。如果需要使用中文則需要使用?load 方法調(diào)用寫好的 *.rb 文件


        (2) 編號識別替換


        對于有明確規(guī)則的編號,正則表達(dá)式可以找出這些編號并加以利用。

        s1="aapid=000022?aibuebcfw@#RD#?pid=002014?ksheFW$#?pid=B36A24"s1.gsub(/pid=([0-9,A-F]{6})/,'^([\1])')#>>?aa^([000022])?aibuebcfw@#RD#?^([002014])?ksheFW$#?^([B36A24])

        以上代碼中的正則表達(dá)式?/pid=([0-9,A-F]{6})/?含義為:以 “pid=” 開始包含 6 位十六進(jìn)制數(shù)位([0-9,A-F])的片段,?{6} 表示前一個方括號表示的字符的重復(fù)次數(shù)為 6。圓括號則用于替換,第一個圓括號所包含的匹配字段用?\1 表示,如果有更多圓括號,則以此類推使用?\2、?\3、?\4……所以最終的效果便是將諸如?“pid=000022” 的片段替換為?“^([000022])”。


        另外需要注意,例子中第二個參數(shù)使用了單引號,雙引號則需要寫成?"^([\\1])" ,因為雙引號字符串中的反斜杠會被當(dāng)做轉(zhuǎn)義符號解讀。


        (3) 斷行處理


        斷行是文本文檔與表格文件對接的重要字符,找到符合條件的斷點非常關(guān)鍵:

        s2="?nah?1200.0?9h?lazarus?3235.1?6h?requiem?1023.5?7h"s2.gsub(/(\s[0-9]+h)/,'\1'+"\r\n")#>>?nah?1200.0?9h#>> lazarus?3235.1?6h#>>?requiem?1023.5?7h

        以上代碼中的?'\1'+"\r\n"?使用了兩種引號就是為了在適當(dāng)?shù)臅r候使用轉(zhuǎn)義符號,也可以直接使用 "\\1\r\n" 這樣的表達(dá)。表達(dá)式?/(\s[0-9]+h)/?表示以空格符號(\s)開始以字符 “h” 結(jié)尾,中間有一個或多個(+)數(shù)字 0-9 的文本片段。


        (4)?調(diào)換順序


        還可以根據(jù)具體要求調(diào)換局部文本的順序:

        s3="27.3324N?116.2132E?42.3324N?102.2132E?10.9323E?79.2214W"s3.gsub(/([0-9\.]+)([NEWS])/,'\2=\1')#>>?N=27.3324?E=116.2132?N=42.3324?E=102.2132?E=10.9323?W=79.2214

        以上代碼中正則表達(dá)式包含兩個圓括號,因此替換字符串可以同時引用?\1\2。表達(dá)式?/([0-9\.]+)([NEWS])/ 表示以一個或多個(+)數(shù)字 0-9 開始,后跟隨小數(shù)點(\.),而后以?NEWS 的其中一個字符結(jié)尾的文本片段。


        (5) 數(shù)字識別處理


        使用正則表達(dá)式還可以很方便的提取出數(shù)字文本:

        s4="1200.0?1212.843?3235.1?4413.31?1023.5?"s4.gsub(/\.([0-9]{,2})\s/,'.\10?').gsub(/\.([0-9]{,2})\s/,'.\10?')#>>?1200.000?1212.843?3235.100?4413.310?1023.500
        s5="lingling 40 hours 3424"s5.gsub(/([0-9]+)(\shours)/,'\1 minutes')#>> lingling 40 minutes 3424

        以上代碼第2行通過連續(xù)兩次?.gsub 方法將小數(shù)點后位數(shù)追加到三位。表達(dá)式?/\.([0-9]{0,2})\s/?表示的是以小數(shù)點(\.)開始以空格符號(\s)結(jié)尾,且中間包含不多于2個({,2})的數(shù)字 0-9,識別小數(shù)部分后在最后追加一個 “0”,以達(dá)到補(bǔ)足小數(shù)位數(shù)的效果。其中的?{,2} 表示前一個方括號代表的字符可以重復(fù)2次及以下。第6行代碼則識別具體的數(shù)量單位并替換。


        (6)?單詞替換


        正則表達(dá)式也可以可以根據(jù)單詞長度或者其他規(guī)則自制填空題:

        s6="A?String?object?holds?and?manipulates?an?arbitrary?sequence?"  +"of bytes, typically representing characters. String objects "  +"may be created using ::new or as literals."#》 s6.gsub(/::[^\s]+/,'___')#>> A String object holds and manipulates an arbitrary sequence #>> of bytes, typically representing characters. String objects #>>?may?be?created?using?___?or?as?literals.

        文中的表達(dá)式?/::[^\s]+/ 表示以 “::” 開頭到空格符號截止的一段文本。其中的?[^\s] 表示除了空格符號(\s)以外的所有符號,符號 “+” 表示一個或更多,相當(dāng)于?{1,} 的表達(dá)。


        (7) 序列


        甚至可以對長文本序列進(jìn)行特定數(shù)位的截斷:

        s6="please?call?01189998819991197253"s6.gsub(/([0-9]{3})/,'\1-')#>>?please?call?011-899-988-199-911-972-53

        根據(jù)正則表達(dá)式的匹配原則,符合條件的文本中的部分片段不會再重新匹配,因此可以實現(xiàn)每隔固定的位數(shù)插入其他字符。


        三、代碼實現(xiàn)


        最后將整個過程封裝在?ApiglioToolBox 模塊中,由于ruby控制臺不支持UTF8輸入,所以直接復(fù)制進(jìn)控制臺時不能使用帶漢字的代碼,所以這里直接使用了轉(zhuǎn)義符號:

        module ApiglioToolBox  def self.file_rep_func(input,output,old,new)    str1=File.read(input)    str2=str1.gsub(old,new)    f=File.open(output,"w")    f.write(str2)    f.close()  end  def self.file_rep()    open_tip="\xe9\x80\x89\xe6\x8b\xa9\xe9\x9c\x80\xe8\xa6\x81\xe6\x9b\xbf\xe6\x8d\xa2\xe5\x86\x85\xe5\xae\xb9\xe7\x9a\x84\xe6\x96\x87\xe6\xa1\xa3"    #選擇需要替換內(nèi)容的文檔    save_tip="\xe6\x9b\xbf\xe6\x8d\xa2\xe7\xbb\x93\xe6\x9e\x9c\xe4\xbf\x9d\xe5\xad\x98\xe4\xb8\xba"    #替換結(jié)果保存為    inpu_tip="\xe6\x9b\xbf\xe6\x8d\xa2\xe9\x80\x89\xe9\xa1\xb9\xef\xbc\x88\xe6\xad\xa3\xe5\x88\x99\xe8\xa1\xa8\xe8\xbe\xbe\xe5\xbc\x8f\xef\xbc\x89"    #替換選項(正則表達(dá)式)    op="\xe6\x9f\xa5\xe6\x89\xbe\xef\xbc\x9a"    #查找:    np="\xe6\x9b\xbf\xe6\x8d\xa2\xe4\xb8\xba\xef\xbc\x9a"    #替換為:    mp="\xe6\xa8\xa1\xe5\xbc\x8f\xef\xbc\x9a"    #模式:    mo_ord="\xe6\x99\xae\xe9\x80\x9a\xe6\xa8\xa1\xe5\xbc\x8f"#普通模式    mo_reg="\xe6\xad\xa3\xe5\x88\x99\xe8\xa1\xa8\xe8\xbe\xbe\xe5\xbc\x8f"#正則表達(dá)式        raise RuntimeError.new("Dialog Cancelled") unless filename=UI.openpanel("FileReplace: "+open_tip)    raise RuntimeError.new("Dialog Cancelled") unless targetname=UI.savepanel("FileReplace: "+save_tip)    patterns=UI.inputbox([op,np,mp],["","",mo_ord],["","",mo_ord+"|"+mo_reg],inpu_tip)    raise RuntimeError.new("Dialog Cancelled") unless patterns    return false if patterns[0]==""    case patterns[2]    when mo_reg      patterns[0]=patterns[0]+"/" if patterns[0][-1]!="/"      patterns[0]="/"+patterns[0] if patterns[0][0]!="/"      puts "ApiglioToolBox.file_rep_func('"+filename+"','"+targetname+"',"+patterns[0]+",'"+patterns[1]+"')"      patterns[0]=eval(patterns[0])    when mo_ord      puts "ApiglioToolBox.file_rep_func('"+filename+"','"+targetname+"',\""+patterns[0]+"\",\""+patterns[1]+"\")"    end    file_rep_func(filename,targetname,*patterns[0..1])    true  endend


        使用這個替換工具只需要在控制臺輸入:

        ApiglioToolBox.file_rep

        而后只需要根據(jù)彈出的對話框進(jìn)行相應(yīng)的設(shè)置即可。當(dāng)然彈出對話框也未必總是那么方便,因此還可以通過調(diào)用?.file_rep_func 方法,通過給定參數(shù)來避免在對話框中設(shè)置參數(shù):

        ApiglioToolBox.file_rep_func(input,output,old_pattern,new_pattern)#input       輸入的文本文檔#output      輸出的文本文檔#old_pattern?需要替換的內(nèi)容(用雙引號包括)#????????????需要替換內(nèi)容的正則表達(dá)式(用斜杠包括)#new_pattern?替換后的內(nèi)容(如不想使用轉(zhuǎn)義符號則使用單引號)#????????????替換內(nèi)容可以增加\1?\2?\3?來引用匹配到的文本


        以下是文本替換工具的使用效果:


        替換前后文件的內(nèi)容如下:



        ?正業(yè)? 這是一個與建模完全無關(guān)的小工具,只是利用 SketchUp 中的 ruby 控制臺的圖靈完備進(jìn)行一些簡易的編程。其存在的意義在于:很多自動化任務(wù)只需要非常簡單的技術(shù)手段,但是為此 beginner 卻需要安裝整套的語言環(huán)境,這是相當(dāng)繁瑣甚至沒有必要的。ruby 控制臺完全省去了安裝開發(fā)環(huán)境的門檻,不需要額外進(jìn)行任何準(zhǔn)備,再加上 ruby 本身的語法特點,使得這類小功能可以很輕松很愉悅的實現(xiàn),對于本就安裝了 SketchUp 的用戶來說十分便利。


        另外,這個工具使用了 UI 模塊中的幾個對話框方法(其實就是系統(tǒng)的對話框)來串聯(lián)整個工具的邏輯,甚至可以給它設(shè)置一個 Toolbar 使之變成一個按鍵,成為典型意義上的插件功能。但是這種連續(xù)跳好幾個對話框的處理方式還是太過冗雜,更合適的做法是使用 UI:: HtmlDialog 做類似于ArcToolBox 的窗口,UI 邏輯會明顯清晰得多。正如本系列創(chuàng)作的初衷,雖然名為“不務(wù)正業(yè)”,但怪異旁門的方法也能夠給“正統(tǒng)”的使用方式以參考借鑒。


        都看到這了,點個贊唄)



        本篇文章是“SketchUp不務(wù)正業(yè)系列”的其中一篇,編號為SU-2021-S02,更多與 SketchUp Ruby有關(guān)的其他文章可以點擊公眾號菜單中的“SU Ruby”選項獲得文章的目錄。


        瀏覽 272
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            精品成人A片久久久久久不卡三区 | 老师的玉臀吞吐着巨龙 | 日韩欧美午夜电影 | 欧美成人网站免费 | 乳尖嗯啊奴婢假山h | 精品欧美色视频网站在线观看 | 插进去在线观看 | 欧美老妇交 | 久久精品视频久久 | 国产又黄又爽免费 |