亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Java 中運行字符串表達式的方法

2024-07-14 08:42:54
字體:
來源:轉載
供稿:網友

在日常的開發中,偶爾會遇到運行字符串表達式的情況,通常這樣的需求會對需求進行進一步分析,然后進行進一步 “特殊化”,最后直接寫到硬代碼中,這樣做的話,就不太好擴展了;也有另外的處理方式是采用 Java 內置的 JavaScript 引擎等運行字符串表達式,但是內置引擎也有弊端,比如頻繁運行片段式的字符串的效率非常低,并且與 Java 之間的數據交互比較麻煩,于是,便產生了寫一個“字符串表達式計算引擎”的想法...

寫的過程其實沒想象中那么麻煩,最初版大概在今年 5 月底寫好,但是結構比較混亂,寫的時候基本上是一邊寫一邊修,最后 if...else...這樣的條件以及嵌套太多,以至于自己也無法完全理解,好在邏輯基本完善,運行也沒出現意料之外的情況(也許出現了,只是沒發現),并且是自己用,所以就沒太在意。

前兩個星期,又抽空重新整理了一遍,重新梳理了一下結構,擴展了一些功能,重新定義了一下各種符號的 “語義邊界”,盡可能保證運算符與 Java 本身運算符一致,邏輯結構也更清晰,不會產生意外情況等。

RunnerUtil 在語法上很大程度參考了 JavaScript 的語法,比如用花括號表示一個鍵值對“對象”(實際上會被解析成 HashMap),鍵名不必用單引號或雙引號包裹,單引號雙引號均表示普通字符串,通過點號(.)和方括號鏈式取值等。這對于從事 JavaWeb 開發的同學來說,書寫起來也比較方便。現在已經實現了絕大部分功能,已實現的功能也經過一定測試,確保能“符合期望”的運行,如果有想法和建議也希望多多的提一下哈。

項目地址: github.com/xua74453185…

基本用法介紹

字符串表達式通過一個叫 RunnerUtil 的靜態類運行,可以直接運行得到表達式結果,也可以解析一個表達式后在需要的時候運行,RunnerUtil 主要有以下幾個方法:

RunnerUtil.run(/* expression */); 直接運行表達式并得到結果;RunnerUtil.run("1 + 1"); // 2RunnerUtil.run(" 'Hello' + ' ' + 'World!' "); // "Hello World!"RunnerUtil.run(/* expression */, / * data */); 運行含有變量的表達式,后面的 data 是變量將要指向的“值”;RunnerUtil.parseRun(/* expression */); 直接運行“另一種”表達式,并得到結果,如:RunnerUtil.parseRun("Hello {{  'World!'  }}"); // "Hello World!"

可見 #parseRun 是運行包含“插值語法”的表達式,被包裹的內容被作為一個表達式單獨運行;

字符串中可以包含多個插值語法表達式,但不能嵌套和交叉,也可以運行含有變量的表達式。

Runner runner = RunnerUtil.parse(/* expression */);

解析一個字符串表達式,得到一個“字符串表達式運行器” —— Runner,然后調用其 run(/ * data */) 方法運行并得到結果。

語法及運算詳細介紹

作為一個具有一定“語言特點”的東西,它定義了一些自己的語法、數據類型、運算類型等,但大部分都與 Java 和 JavaScript 兼容,相同符號具有相同或相似的語言意義。

數據類型:

1、null:這是一個關鍵字,但因為它符合和變量的定義規則,所以需要注意一下,同樣被定義為關鍵字的還有 true 和 false。

2、boolean:true 和 false

RunnerUtil.run(" null  "); // nullRunnerUtil.run("  true "); // trueRunnerUtil.run("false"); // false// 表達式中多余的空格自動忽略

數字:這里面的數字統一采用 Java 里的 int 和 double 型數據,直接參與運算的也只有是這兩種類型,區別就是有沒有小數點。

RunnerUtil.run(" 12 "); // 12RunnerUtil.run(" 12.5 "); // 12.5// 表示數字必須是連續,中間不能有空格的// 否則將拋出異常,如RunnerUtil.run(" 12. 5"); // 異常RunnerUtil.run(" 1 2 "); // 異常

表示數字的字符之間應該是連續的,如:25、36.9 等;如果是不連續的會拋出異常,如:2 5、36 .9 等;

字符串:Java 里的字符串用雙引號包裹,在這里還將表示字符的單引號“征用”,雙引號單引號包裹的都表示普通字符串的直接值,這樣做也是為了書寫方便(與 JavaScript 相似),同時也就沒有了 char 類型數據啦啦啦……

RunnerUtil.run(" 'abcdef' "); // "abcdef"RunnerUtil.run(" /"abcdef/" "); // "abcdef"RunnerUtil.run(" 'abc  def' "); // "abc  def"

List:實際上是 ArrayList,對應 JavaScript 里面的數組。Java 的數組也對應 JavaScript 數組。

RunnerUtil.run(" { } "); // 總是返回一個空ArrayListRunnerUtil.run(" {1,2,,4, } "); // 總是返回一個包含:1、2、null、4 這幾項的 ArrayList// 可以看出最后一個逗號之后如果是結束符號會自動忽略// 中間的逗號與逗號之間若沒有其他非空白符號會插入一個 null 值

Map:實際上是 HashMap,對應 JavaScript 里的對象。同樣對應 JavaScript 對象的還有普通 POJO。
Map 對應的是 JavaScript 里的對象,但是在這里 Map 的鍵可以是這些數據類型:

null、true / false、數字(int / double)、字符串,不能再是其他 Java 對象了

RunnerUtil.run(" {:} "); // 總是返回一個空 HashMap,// 注意與空 List 的異同,都是用花括號表示// 但空 Map 里面需要有一個冒號,否則就是 ListRunnerUtil.run(" {key: 'value'}");// 總是返回包含一個鍵值對的 HashMap// 可以看出,對象的鍵名是字符串的話可以不用引號包裹// 但是值必須被包裹RunnerUtil.run(" {true: 'value'}"); // 鍵是 true/* * 這里的 true 不是字符串,而是 boolean。 * 同樣,未被引號包裹的 null、false、數字都是對應類型的數據,而不是字符串 * 其他符合變量命名規則的鍵都是普通字符串,被單引號或雙引號包裹的也是 */RunnerUtil.run(" {'true': 'value', 25: false, 'name': /"張三/"}");

運算支持的類型:

普通四則混合運算:+、-、*、/、%、()RunnerUtil.run(" 1 + 1 "); // 2RunnerUtil.run(" 1 + (3 * 4)) "); // 13RunnerUtil.run(" 'Hello ' + /"World!/" "); // "Hello World!"RunnerUtil.run(" true + false "); // "truefalse"/* * true+false 在 Java 中是不允許的 * 但如果是“+”運算的話,這里均作為普通字符串; * 相當于調用了 toString 方法 */位運算:&、|、^、<<、>>RunnerUtil.run(" 1 ^ 1 "); RunnerUtil.run(" 1 & 1 "); RunnerUtil.run(" 1 | 1 "); RunnerUtil.run(" 1 << 1 "); RunnerUtil.run(" 1 >> 1 ");比較運算:>、>=、==、<=、<RunnerUtil.run(" 1 + 1 == 2 "); // trueRunnerUtil.run(" 1 + 1 < 2 "); // false邏輯運算:&&、||、!RunnerUtil.run("1+1==2 && 5 > 4"); // true變量:命名規則與 Java 變量命名規則相同,同時 null、true、false 不能作為變量表達式中包含變量就代表這個表達式在運行得到結果時需要從外部獲取數據,如果不能正確的從數據源讀取到數據,運行就會拋出異常;RunnerUtil.run(" 'Hello, ' + name "); // 拋出異常Map data = new HashMap();data.put("name", "Li Lei!");RunnerUtil.run(" 'Hello, ' + name ", data); // "Hello, Li Lei!"

鏈式取值:鏈式語法與 JavaScript 很相似

HashMap data = new HashMap(); ArrayList list = new ArrayList(); list.add(true); list.add(false); list.add(25); list.add('隔壁老王'); HashMap map = new HashMap(); map.put("name", "小四"); map.put("index", 2); map.put(true, "true 是 Boolean 類型作為鍵"); data.put("list", list); data.put("map", map); RunnerUtil.run("map.name", data); // "小四"RunnerUtil.run("map['name']", data); // "小四" (也可以這樣取值)RunnerUtil.run("list[ 2 ]", data);// 25 (索引取值需要用方括號包裹) RunnerUtil.run("list[3]", data);// "隔壁老王" (索引取值需要用方括號包裹) RunnerUtil.run("list[map.index]", data); // 25// (這是高級點的用法,方括號包含另一個表達式// 返回值是一個索引,然后返回索引指向的值)RunnerUtil.run("[true]", data); // "true 是 Boolean 類型作為鍵"// 如果不用方括號包括,true 就是一個直接值,返回 true// 那么問題來了:// 如果傳入的數據不是 Map 或 POJO,而是 List 或數組怎么辦呢?RunnerUtil.run(" [1] ", list); // false// 啊……唐宗宋祖,略顯風騷!// 這種鏈式語法與 JavaScript 很相似

運行方法:目前只能運行無參和一個參數的方法,變長參數的方法支持不完善,慎用。
這里的數據 data 繼續用上一條的 data,具體數據不寫了

RunnerUtil.run("map.size()", data); // 3RunnerUtil.run("map.get('name')", data); // "小四" RunnerUtil.run("map.get('name').length()", data); // 2RunnerUtil.run("map.name.length()", data); // 2RunnerUtil.run(" [3].length() ", list); // 4// 唐宗宋祖,又顯風騷!

運行靜態方法: @ ;運行靜態方法需要用到“@”符號作為標記。目前也不支持多參數方法調用。
當你打開源碼會發現這是一整個獨立的工具庫,很多方法和 commons-lang 包內容相似(個人認為不是重復造輪子,也有很多不同的和不如的)...,運行靜態方法也可以運行這個工具庫內的所有工具方法,暫時未將 RunnerUtil 剝離出來,也還不支持自定義的靜態方法調用,不過這個工具庫所提供的功能

RunnerUtil.run("@System.currentTimeMillis() ");// 15.....(一個毫秒數)RunnerUtil.run("@Objects.toString(25) "); // "25"

綜上,就是這個工具庫所支持的字符串表達式運算了,以上所列舉的運算可以嵌套、連接、但是不能交叉的進行運算。接下來要做的是加入的功能是多參數方法調用,希望對大家的日常開發有所幫助,也希望大家給點意見,如出現 BUG 一定在最快的時間內修改,謝謝大家啦啦啦??!

總結

以上所述是小編給大家介紹的Java 中運行字符串表達式的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
性色av香蕉一区二区| 欧美黑人性生活视频| 色狠狠av一区二区三区香蕉蜜桃| 91av在线播放| 在线亚洲午夜片av大片| 日韩影视在线观看| 日韩精品久久久久久久玫瑰园| 国产69精品久久久久9| 国产精品日韩在线观看| 国产精品久久久久9999| 国产精品第一第二| 成人免费高清完整版在线观看| 欧美激情亚洲精品| 欧美极品美女电影一区| 国产精品视频资源| 国产日韩在线免费| 国产在线拍偷自揄拍精品| 久久久国产一区二区| 国产性猛交xxxx免费看久久| 国模精品视频一区二区三区| 97欧美精品一区二区三区| 久久精品99久久久久久久久| 欧美激情一区二区久久久| 亚洲香蕉在线观看| 亚洲va国产va天堂va久久| 国产精品99免视看9| 97视频在线看| 成人激情视频免费在线| zzjj国产精品一区二区| 亚洲欧美在线x视频| 国产精品福利小视频| 中日韩午夜理伦电影免费| 亚洲性xxxx| 97超级碰碰碰久久久| 欧美黄色片在线观看| 最近的2019中文字幕免费一页| 一区二区三区美女xx视频| 国产精品视频一| 国产精品直播网红| 日本不卡视频在线播放| 日韩av综合网站| 欧美激情精品久久久久久| 91po在线观看91精品国产性色| 国产欧美日韩精品丝袜高跟鞋| 久久久久日韩精品久久久男男| 日韩国产精品视频| 精品亚洲一区二区三区四区五区| 精品色蜜蜜精品视频在线观看| 国产激情999| 精品av在线播放| 国产精品夜色7777狼人| 日韩中文字幕网站| 欧美性感美女h网站在线观看免费| 亚洲欧美在线磁力| 欧美在线观看日本一区| 国产乱肥老妇国产一区二| 国产精品一二三在线| 国产成人精品久久| 亚洲第一网站男人都懂| 亚洲免费小视频| 视频在线观看99| 69影院欧美专区视频| 亚洲欧美日韩在线高清直播| 国产精品一区av| 国产视频亚洲精品| 日韩禁在线播放| 日韩高清免费在线| 性欧美xxxx| 久久天天躁狠狠躁夜夜av| 国产成人高清激情视频在线观看| 亚洲天堂成人在线| 亚洲xxx自由成熟| 久久综合伊人77777| 国产精品欧美在线| 91久久精品国产91久久| 日韩精品在线免费播放| 久久久久免费精品国产| 欧美午夜精品久久久久久久| 中文字幕成人精品久久不卡| 黑人巨大精品欧美一区二区一视频| 国产视频久久久久| 91夜夜未满十八勿入爽爽影院| 国产精品一区二区女厕厕| 夜色77av精品影院| 日本欧美一级片| 91九色在线视频| 国产午夜精品全部视频播放| 成人有码视频在线播放| 日韩免费高清在线观看| 亚洲成人av片在线观看| 日韩av最新在线观看| 91超碰caoporn97人人| 欧美午夜片欧美片在线观看| 久久99精品视频一区97| 久久久久九九九九| 色综合久久精品亚洲国产| 国产欧美日韩视频| 欧美午夜影院在线视频| 亚洲男人天堂网站| 51ⅴ精品国产91久久久久久| 日韩精品日韩在线观看| 视频一区视频二区国产精品| 国内精品久久久久久久| 欧美一级大胆视频| 夜夜狂射影院欧美极品| 国产视频久久久| 亚洲第一精品夜夜躁人人躁| 成人情趣片在线观看免费| 在线中文字幕日韩| 欧美成人免费视频| 欧美成人一区二区三区电影| 久久99国产精品自在自在app| 欧美日韩国产va另类| 亚洲综合av影视| 亚洲综合国产精品| 亚洲国产精品中文| 日韩视频在线观看免费| 国产91精品黑色丝袜高跟鞋| 亚洲香蕉在线观看| 亚洲综合精品一区二区| 91精品视频在线播放| 日韩欧美在线免费观看| 亚洲一区二区日本| 国产欧美一区二区三区在线看| 国产99在线|中文| 日本韩国欧美精品大片卡二| 在线观看精品自拍私拍| 九九九久久久久久| 国产精品96久久久久久| 日韩精品黄色网| 欧美精品性视频| 91久久精品日日躁夜夜躁国产| 成人免费大片黄在线播放| 精品国产一区二区三区四区在线观看| 欧美成人免费一级人片100| 欧美激情videos| 亚洲一区二区三区xxx视频| 日韩免费电影在线观看| 亚洲级视频在线观看免费1级| 久久国产精品久久久久久久久久| 中文欧美日本在线资源| 全亚洲最色的网站在线观看| 91成人天堂久久成人| 日韩免费黄色av| 国产在线高清精品| 欧美www视频在线观看| 欧美视频国产精品| 日韩精品免费视频| 久久久久免费精品国产| 琪琪亚洲精品午夜在线| 久久精品国产亚洲| 久久亚洲一区二区三区四区五区高| 亚洲成人999| 中文字幕日韩专区| 亚洲影院色无极综合| 性色av一区二区三区红粉影视| 日韩国产高清污视频在线观看| 欧美在线观看网址综合| 欧美综合一区第一页| 亚洲第一福利视频| 亚洲a成v人在线观看| 国产精品三级网站| 国产欧美日韩视频| 欧美国产激情18|