我需要按以下方式格式化电话号码:
例如:(03069) 990927
将变为:3069990927
。
到目前为止,我已经提出了这个问题:
replace(replace(replace(replace(replace(replace(substr(replace(ltrim([VALUE],0), ' ', ''),nvl(length(substr(replace(ltrim([VALUE],0), ' ', ''),11)),0)+1), '-', ''), '(', ''), ')', ''),'/', ''), '.', ''), '+', '')
是否有更短的版本,可能使用正则表达式?
此代码段的最终版本将成为视图中的一列,该列将返回以下列:
格式化的电话号码将与表格中保存在数据库中的国际拨号代码(例如+44)连接 - DIALCODE_TAB(COUNTRY_CODE,CODE)。以下是使用上述replace
语法的示例:
CREATE OR REPLACE FORCE VIEW "CUST_PHONE" ("CUSTOMER_ID", "NAME", "COUNTRY", "PHONE_NUMBER") AS
select
cicm.customer_id,
cicm.name,
dct.country,
dct.code || replace(replace(replace(replace(replace(replace(substr(replace(ltrim(cicm.value,0), ' ', ''),nvl(length(substr(replace(ltrim(cicm.value,0), ' ', ''),11)),0)+1), '-', ''), '(', ''), ')', ''),'/', ''), '.', ''), '+', '') phone_number
from customer_info_comm_method cicm
join dialcode_tab dct
on dct.country_code = customer_info_api.get_country_code(cicm.customer_id)
where cicm.method_id_db = 'PHONE'
--and dct.code || replace(replace(replace(replace(replace(replace(substr(replace(ltrim(cicm.value,0), ' ', ''),nvl(length(substr(replace(ltrim(cicm.value,0), ' ', ''),11)),0)+1), '-', ''), '(', ''), ')', ''),'/', ''), '.', ''), '+', '') = [phone_number]
--in terms of performance this SQL has to be written so that it returns all the records or a specific record when searching for the phone number - very quickly (<10s).
WITH read only;
N.B。客户记录可以包含1个以上的电话号码,并且可以在1个以上的客户记录中存在相同的电话号码。
答案 0 :(得分:2)
首先要注意:这只适用于国家/地区存储在其他地方以进行记录且没有没有区号的电话号码的情况。否则,将无法再次重建完整的电话号码。
然后:您的数据中如何显示国家/地区代码?总是+44还是0044?这里要小心。特别是不要删除单个零(假设它是区号),当它实际上是代表国家代码的两个零中的第一个时: - )
然后:您需要所有国家/地区代码的列表。我们以+1441441441为例。国家代码在哪里结束? (解决方案:+1441是百慕达。)
对于“无空格”和“无特殊字符”,您可以使用regexp_replace解决此问题。
总而言之,这并不像你明显期望的那么简单。 (但也不难做到。)
我会使用PL / SQL。
希望我的提示可以帮到你。祝你好运。
编辑:这是需要的。我仍然认为PL / SQL函数在这里最好。
确保您的DIALCODE_TAB包含所有必需的国家/地区代码。
1. Trim the phone number.
2. Then check if its starts with a country identifyer (+, 00).
2.1. If so: remove that. Remove all non-digits. Look up the country code in your table and remove it.
2.2. If not so: check if it starts with an area identifyer (0).
2.2.1. If so: remove it.
2.2.2. In any case: remove all non-digits.
如果数字有效,应该这样做。在德国,有时人们写+49(0)40-123456,这是无效的,因为一个要么使用国家代码或区号,而不是两者数。必须删除(0)以使该数字有效。
答案 1 :(得分:1)
SELECT LTRIM(REGEXP_REPLACE(
REGEXP_REPLACE('+44(03069) 990927',
'(\+).([[:digit:]])+'), -- to strip off country code
'[^[:alnum:]]'),-- Strip off non-aplanumeric [:digit] if only digit
'0') -- Remove preceding Zero
FROM DUAL;
不适用于+44990927 (如果国家/地区代码没有任何空格或某些内容或国家/地区没有以+开头)
答案 2 :(得分:1)
Oracle 11g R2架构设置:
CREATE TABLE phone_numbers ( phone_number ) AS
SELECT '(03069) 990927' FROM DUAL
UNION ALL SELECT '+44 1234 567890' FROM DUAL
UNION ALL SELECT '+44(0)1234 567890' FROM DUAL
UNION ALL SELECT '+44(012) 34-567-890' FROM DUAL
UNION ALL SELECT '+44-1234-567-890' FROM DUAL
UNION ALL SELECT '+358-1234567890' FROM DUAL;
查询1 :
如果您只是处理+44
国际拨号代码,那么您可以:
^\+44|\D
去除+44
国际代码和所有非数字字符;然后^0
去除前导零(如果存在)。像这样:
SELECT REGEXP_REPLACE(
REGEXP_REPLACE(
phone_number,
'^\+44|\D',
''
),
'^0', '' ) AS phone_number
FROM phone_numbers
<强> Results 强>:
| PHONE_NUMBER |
|---------------|
| 3069990927 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
| 3581234567890 |
(你可以看到它对于带有+358国际代码的最终号码不起作用。)
查询2 :
这可以简化为单个正则表达式(可读性稍差):
SELECT REGEXP_REPLACE(
phone_number,
'^(\+44)?\D*0?|\D',
''
) AS phone_number
FROM phone_numbers
<强> Results 强>:
| PHONE_NUMBER |
|---------------|
| 3069990927 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
| 3581234567890 |
查询3 :
如果您想处理多个国际拨号代码,则需要知道哪些有效(请参阅http://en.wikipedia.org/wiki/List_of_country_calling_codes获取列表)。
这是一个正则表达式示例,它会删除以+3
,+4
或+5
开头的有效国际拨号代码(我会留下所有其他拨号代码给您编码):
SELECT REGEXP_REPLACE(
phone_number,
'^(\+(3[0123469]|3[57]\d|38[01256789]|4[013456789]|42[013]|5[09]\d|5[12345678]))?\D*0?|\D',
''
) AS phone_number
FROM phone_numbers
<强> Results 强>:
| PHONE_NUMBER |
|--------------|
| 3069990927 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
| 1234567890 |
如果国际拨号代码开头的+
是可选的,那么只需用\+
替换\+?
(正则表达式的开头附近)。