在每次從字母數字到數字的變化之後,是否可以幫助我分割一個字符串(或者首選,如果可能,請在每個「拆分」場合放置一個空格),反之亦然?正則表達式:拆分字符串字母數字/數字
所以像D2c1 22
這樣的字符串應該看起來像D 2 c 1 22
。最好的辦法是對從字母數字到數字的每一個變化都留下一個空白。
在每次從字母數字到數字的變化之後,是否可以幫助我分割一個字符串(或者首選,如果可能,請在每個「拆分」場合放置一個空格),反之亦然?正則表達式:拆分字符串字母數字/數字
所以像D2c1 22
這樣的字符串應該看起來像D 2 c 1 22
。最好的辦法是對從字母數字到數字的每一個變化都留下一個空白。
下面是PostgreSQL的測試的方法和驗證工作。這有點折磨,所以表演可能會......有趣。
CREATE AGGREGATE array_cat_agg (
BASETYPE = anyarray,
SFUNC = array_cat,
STYPE = anyarray
);
SELECT array_to_string(array_cat_agg(a), ' ')
FROM regexp_matches('234kjh23ljkgh34klj2345klj', '(\D*)(\d*)', 'g') x(a);
我們需要array_cat_agg
因爲經常array_agg
不能陣列的總陣列。
或者,@ davidrac的做法的一種形式,將與PostgreSQL的工作,可能會表現更好顯著(雖然我還沒有測試)是:
SELECT regexp_replace(
regexp_replace(
'234kjh23ljkgh34klj2345klj', '(\d)(\D)', '\1 \2', 'g'
), '(\D)(\d)', '\1 \2', 'g');
這是執行在兩次傳球替換。首先它插入一系列數字結束和一系列非數字開始的空間。然後在另一個通行證中插入一系列非數字結尾和一系列數字開始的空格。
更新:下面是一個改進配方:
SELECT trim(regexp_replace('234kjh23ljkgh34klj2345klj', '(?!\d)(\D+)|(?!\D)(\d+)', '\1\2 ', 'g'));
@davidrac驗證您的第二個配方與Pg配合使用。上面的Pg以及更早的(更醜陋的)實現。爲你的答案+1了。 –
謝謝。但我膽量完全相同的測試字符串(234kjh23ljkgh34klj2345klj)結果當我嘗試上述的SQL與雙regexp_replace – calimero
@calimero你可以在'standard_conforming_strings'更改之前使用舊版本的PostgreSQL(9.0或更早版本)嗎?嘗試'SET standard_conforming_strings = on;'然後再次測試。 (這就是爲什麼你總是在提問中提到你的PostgreSQL版本的原因)。如果它適用於'standard_conforming_strings',那麼(a)升級PostgreSQL並(b)參見http://www.postgresql.org/docs/current/static/runtime-config-compatible.html#GUC-STANDARD-CONFORMING- STRINGS用於如何在不升級PostgreSQL的情況下使查詢生效。基本上,而不是''''使用'E'\\'';雙反斜槓並使用'E''。 –
您可以使用此正則表達式找到的地方則切換:
(?<=\d)(?=\D)|(?<=\D)(?=\d)
這樣:
"234kjh23ljkgh34klj2345klj".gsub(/(?<=\d)(?=\D)|(?<=\D)(?=\d)/, " ")
=> "234 kjh 23 ljkgh 34 klj 2345 klj"
編輯:沒有零長度向前看和向後看:
"234kjh23ljkgh34klj2345klj".gsub(/(\d)(\D)/, "#{$1} #{$2}").gsub(/(\D)(\d)/, "#{$2} #{$1}")
=> "23 jk 5 jkgk 5 lk 534 lj"
Pg(至少9.2)似乎不明白,正則表達式,不幸的是, 。 (?= \ D)(?<= \ D)(?)?????選擇regexp_replace('234kjh23ljkgh34klj2345klj','(?<= \ d)= \ d)','','g');' '錯誤:無效正則表達式:量詞操作數無效。請參閱http://sqlfiddle.com/#!12/d41d8/148 –
它可能無法處理零長度的向前看和向後看。在這種情況下,你可以使用類似這種方法(這是ruby語法,所以你必須調整):「234kjh23ljkgh34klj2345klj」.gsub(/(\ d)(\ D)/,「#{$ 1}#{$ 2 }「)。gsub(/(\ D)(\ d)/,」#{$ 2}#{$ 1}「) =>」23 jk 5 jkgk 5 lk 534 lj「 – davidrac
pg中的lookahead語法doc):(?= re)\t在子字符串匹配重新開始的任何點上的正向預測匹配 (?!re)\t負向預測匹配在沒有子字符串匹配重新開始的任何點上(僅限ARE) – davidrac
把Best way from would be to put a blank at every change from alpha-numeric to numeric.
它並不難做到:
$ echo "D2c1 22" | sed 's|\([a-ZA-Z]\)\([0-9]\)|\1 \2|g;s|\([0-9]\)\([a-ZA-Z]\)|\1 \2|g'
D 2 c 1 22
在這裏,我用sed
和正則表達式,因爲你沒有提到你使用的語言。主要思想是使用2個正則表達式替換alpha與數字和數字與alpha到第一個字符,空格和第二個字符。
非常感謝快速的共鳴。我想在postgresql中完成它。 – calimero
作爲@ davidrac的解決方案,似乎Pg的正則表達式引擎無法應對該問題。請參閱http://sqlfiddle.com/#!12/d41d8/148 –
通常更好的方法是使用'\ d'和'\ D',這樣您就可以處理任何數字和非數字序列,而不僅僅是小寫字母數字。 –
我可以幫你,但你不能做到這一點。 –
有點相關的是這個關於自然排序包含數字和非數字序列混合的字符串的問題。其中的一些查詢可能對您有用。 http://stackoverflow.com/questions/12965463/humanized-or-natural-number-sorting-of-mixed-word-and-number-strings –