<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 6899字,需瀏覽 14分鐘

           ·

          2021-12-31 11:24


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


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


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


          【本期目錄】

          一、替換文本的流程

          二、正則表達(dá)式

          三、代碼實(shí)現(xiàn)

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




          一、替換文本的流程


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

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

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

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

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


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

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


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


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

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


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


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

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


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

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


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


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

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


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


          二、正則表達(dá)式


          關(guān)于正則表達(dá)式,這里只提供一些感性的例子,詳細(xì)的語法規(guī)則和使用方法不是本篇文章能夠概括的??梢詤⒖家韵聝蓚€(gè)網(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ī)避某些有特殊含義的符號(hào):

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


          (2) 編號(hào)識(shí)別替換


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

          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} 表示前一個(gè)方括號(hào)表示的字符的重復(fù)次數(shù)為 6。圓括號(hào)則用于替換,第一個(gè)圓括號(hào)所包含的匹配字段用?\1 表示,如果有更多圓括號(hào),則以此類推使用?\2、?\3、?\4……所以最終的效果便是將諸如?“pid=000022” 的片段替換為?“^([000022])”。


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


          (3) 斷行處理


          斷行是文本文檔與表格文件對(duì)接的重要字符,找到符合條件的斷點(diǎn)非常關(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"?使用了兩種引號(hào)就是為了在適當(dāng)?shù)臅r(shí)候使用轉(zhuǎn)義符號(hào),也可以直接使用 "\\1\r\n" 這樣的表達(dá)。表達(dá)式?/(\s[0-9]+h)/?表示以空格符號(hào)(\s)開始以字符 “h” 結(jié)尾,中間有一個(gè)或多個(gè)(+)數(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á)式包含兩個(gè)圓括號(hào),因此替換字符串可以同時(shí)引用?\1\2。表達(dá)式?/([0-9\.]+)([NEWS])/ 表示以一個(gè)或多個(gè)(+)數(shù)字 0-9 開始,后跟隨小數(shù)點(diǎn)(\.),而后以?NEWS 的其中一個(gè)字符結(jié)尾的文本片段。


          (5) 數(shù)字識(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ù)點(diǎn)后位數(shù)追加到三位。表達(dá)式?/\.([0-9]{0,2})\s/?表示的是以小數(shù)點(diǎn)(\.)開始以空格符號(hào)(\s)結(jié)尾,且中間包含不多于2個(gè)({,2})的數(shù)字 0-9,識(shí)別小數(shù)部分后在最后追加一個(gè) “0”,以達(dá)到補(bǔ)足小數(shù)位數(shù)的效果。其中的?{,2} 表示前一個(gè)方括號(hào)代表的字符可以重復(fù)2次及以下。第6行代碼則識(shí)別具體的數(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]+/ 表示以 “::” 開頭到空格符號(hào)截止的一段文本。其中的?[^\s] 表示除了空格符號(hào)(\s)以外的所有符號(hào),符號(hào) “+” 表示一個(gè)或更多,相當(dāng)于?{1,} 的表達(dá)。


          (7) 序列


          甚至可以對(duì)長文本序列進(jìn)行特定數(shù)位的截?cái)啵?br>

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

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


          三、代碼實(shí)現(xiàn)


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

          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"    #替換選項(xiàng)(正則表達(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


          使用這個(gè)替換工具只需要在控制臺(tái)輸入:

          ApiglioToolBox.file_rep

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

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


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


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



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


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


          都看到這了,點(diǎn)個(gè)贊唄)



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


          瀏覽 272
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产第一页在线观看 | 日韩无码av中文字幕 | 成人无码视频网站 | 99热这里都是精品 | 日韩水逼|