企業(yè)怎么做網(wǎng)絡(luò)推廣拼多多seo搜索優(yōu)化
[Python學(xué)習(xí)日記-53] Python 中的正則表達(dá)式模塊 —— re
簡(jiǎn)介
re 模塊
練習(xí)
簡(jiǎn)介
? ? ? ? 我們?cè)诰幊痰臅r(shí)候經(jīng)常會(huì)遇到想在一段文字當(dāng)中找出電話號(hào)碼、身份證號(hào)、身高、年齡之類的信息,就像下面的數(shù)據(jù)一樣
# 文件名:美麗學(xué)姐聯(lián)系方式.txt
姓名????????地區(qū)? ? ? ? 身高? ? ? ? 體重? ? ? ? 電話
馬纖羽????????深圳????????173????????50????????13744234523
喬亦菲????????廣州????????172????????52????????15823423525
羅夢(mèng)竹????????北京????????175????????49????????18623423421
柳如煙????????北京????????170????????48????????18623423765
岳妮妮????????深圳????????177????????54????????18835324553
賀婉萱????????深圳????????174????????52????????18933434452
葉梓萱????????上海????????171????????49????????18042432324
? ? ? ? 那我們現(xiàn)在需要取出里面的所有手機(jī)號(hào),你能想到的辦法是什么?應(yīng)該是下面這一種吧
f = open("美麗學(xué)姐聯(lián)系方式.txt","r",encoding="utf-8")phones = []for line in f:name,city,height,weight,phone = line.split()if phone.startswith("1") and len(phone) == 11:phones.append(phone)print(phones)
代碼輸出如下:
? ? ? ? 從輸出來看這的確是達(dá)到了我們想要的效果了,但是我們卻為了這個(gè)小功能寫下了相對(duì)復(fù)雜的代碼,有沒有更簡(jiǎn)單的方式呢?手機(jī)號(hào)是有規(guī)則的,都是數(shù)字且是11位,而且都是1開頭的,如果能把這樣的規(guī)則寫成代碼,直接拿規(guī)則代碼匹配文件內(nèi)容不就行了?而這種玩法就叫做正則表達(dá)式!
import ref = open("美麗學(xué)姐聯(lián)系方式.txt","r",encoding="utf-8")phone_line = re.findall("[0-9]{11}",f.read())
print(phone_line)
代碼輸出如下:
re 模塊
????????正則表達(dá)式就是字符串的匹配規(guī)則,在多數(shù)編程語言里都有相應(yīng)的支持,Python 里對(duì)應(yīng)的模塊就是 re 模塊。
一、Flags 標(biāo)志符
注:括號(hào)內(nèi)是完整寫法
- re.I(re.IGNORECASE):忽略大小寫
- re.M(re.MULTILINE):多行模式,改變“^”和“$”的行為
- re.S(re.DOTALL):改變“.”的行為,使“.”能匹配上換行符(\n)
- re.X(re.VERBOSE):可以給你的表達(dá)式寫注釋,使其更可讀,下面兩個(gè)代碼是一樣的
import rea = re.compile(r"""\d + # the integral part\. # the decimal point\d * # some fractional digits""",re.X)
b = re.compile(r"\d+\.\d*") # 不一定要加r,可以把\變成\\print(a.findall("172.16.11.11"))
print(b.findall("172.16.11.11"))
代碼輸出如下:
二、匹配語法
1、re.match
????????從頭開始匹配從起始位置開始根據(jù)正則表達(dá)式去字符串中匹配指定內(nèi)容,只進(jìn)行一次匹配,語法如下
re.match(pattern,string,flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- string:要匹配的字符串
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
演示代碼如下
import reobj = re.match('\\d+','123uuas133f') # 如果能匹配到就返回一個(gè)可調(diào)用的對(duì)象,否則返回Noneif obj:print(obj.group())
代碼輸出如下:
2、re.search
????????根據(jù)正則表達(dá)式去字符串中匹配指定包含的內(nèi)容,只進(jìn)行一次匹配,語法如下
re.search(pattern,string,flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- string:要匹配的字符串
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
演示代碼如下?
import reobj = re.search('\\d+','u321uu888asf')if obj:print(obj.group())
代碼輸出如下:
3、re.findall
????????match() 和 search() 均用于匹配單值(只能匹配字符串中的一個(gè)),如果想要匹配到字符串中所有符合條件的元素,則需要使用 findall()(把所有匹配到的字符放到列表中,并以列表的形式返回),語法如下
re.findall(pattern,string,flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- string:要匹配的字符串
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
演示代碼如下??
import reobj = re.findall('\\d+','fa123uu888asf')
print(obj)
代碼輸出如下:
4、re.split
????????用匹配到的值做為分割點(diǎn),把字符串分割成列表,語法如下
re.split(pattern,string,maxsplit=0,flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- string:要匹配的字符串
- maxsplit:最大分割數(shù)
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
演示代碼如下??
import reprint(re.split("[0-9]", "askm3kms4msjmn6nkna8lna")) # 以匹配到的字符作為分隔符
print(re.split("\\d", "askm3kms44msjmn6nkna8lna"))s = '9-2*5/3+7/3*99/4*2998+10*568/14'
print(re.split(r"[-+*/]", s))
print(re.split(r"[-+*/]", s,3))
代碼輸出如下:
5、re.sub
????????用于替換匹配的字符串,比 str.replace() 功能更加強(qiáng)大,語法如下
re.sub(pattern, repl, string, count=0, flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- repl:替換為該字符
- string:要匹配的字符串
- count:要替換的次數(shù)
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
演示代碼如下?
import reprint(re.sub('[a-z]+','handsome',"我是abc123"))
print(re.sub('\\d+','|','alex22wupeiqi33o1dboy55',count=2))
代碼輸出如下:
6、re.fullmatch
????????把整個(gè)字符串匹配成功就返回一個(gè)?re 對(duì)象,否則返回None,語法如下
re.fullmatch(pattern,string,flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- string:要匹配的字符串
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
import reprint(re.fullmatch('\\w+@\\w+\\.(com|cn|edu)','jove@csdn.cn'))
代碼輸出如下:
7、re.compile
????????提前將正則表達(dá)式模式編譯成一個(gè)正則表達(dá)式對(duì)象的函數(shù),該對(duì)象可以使用 match()、search() 等其他方法進(jìn)行匹配,這樣的好處是什么呢?要知道之所以正則表達(dá)式可以實(shí)現(xiàn)這些功能是因?yàn)樗趫?zhí)行的時(shí)候都會(huì)生成一個(gè)相應(yīng)功能的函數(shù),當(dāng)結(jié)束的時(shí)候就會(huì)釋放它,但是如果這里有成百上億條數(shù)據(jù)需要使用同樣的正則表達(dá)式處理,那么生成函數(shù)這個(gè)動(dòng)作就要做非常多次,這樣再強(qiáng)的 CPU 也會(huì)吃不消的,這樣我們使用 compile() 提前編譯好,然后保存下來,然后調(diào)用就可以節(jié)省非常多的資源了,語法如下
re.compile(pattern, flags=0)
參數(shù)說明:
- pattern:正則表達(dá)式
- flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式
演示代碼如下?
import re# 假設(shè)現(xiàn)在要處理1億個(gè)身份證信息
ids = ["4406821992010216521","4406821987020217521","4406821956030215731","4406821999042814691"] # 假設(shè)列表中存了1億個(gè)身份證信息
result = {} # 用于存儲(chǔ)處理后的結(jié)果prog = re.compile("(?P<province>[0-9]{3})(?P<city>[0-9]{3})(?P<birthday>[0-9]{8})(?P<small_man>[0-9X]{5})")for i in ids:# 循環(huán)了1億次result[i] = prog.search(i).groupdict()print(result)
代碼輸出如下:
{
'4406821992010216521':
????????{'province': '440', 'city': '682', 'birthday': '19920102', 'small_man': '16521'},
'4406821987020217521':
????????{'province': '440', 'city': '682', 'birthday': '19870202', 'small_man': '17521'},
'4406821956030215731':
????????{'province': '440', 'city': '682', 'birthday': '19560302', 'small_man': '15731'},
'4406821999042814691':
????????{'province': '440', 'city': '682', 'birthday': '19990428', 'small_man': '14691'}
}
三、常用的表達(dá)式規(guī)則
1、總表
符號(hào) | 說明 |
---|---|
. | 默認(rèn)匹配除 \n 之外的任意一個(gè)字符,若指定 flag DOTALL,則匹配任意字符,包括換行 |
^ | 匹配字符開頭,若指定 flags MULTILINE,這種也可以匹配上 (r"^a","\nabc\neee",flags=re.MULTILINE),取反,re.search(r'[^()]',1(2)) 這里會(huì)輸出1 |
$ | 匹配字符結(jié)尾, 若指定 flags MULTILINE,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 會(huì)匹配到 foo1 |
* | 匹配 * 號(hào)前的字符0次或多次, re.search('a*','aaaabac') 結(jié)果'aaaa' |
+ | 匹配前一個(gè)字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 結(jié)果 ['ab', 'abb'] |
? | 匹配前一個(gè)字符1次或0次,re.search('b?','jove').group() 匹配 b 0次 |
{m} | 匹配前一個(gè)字符 m 次,re.search('b{3}','jovebbbs').group() 匹配到'bbb' |
{n,m} | 匹配前一個(gè)字符 n 到 m 次,re.findall("ab{1,3}","abb abc abbcbbb") 結(jié)果 ['abb', 'ab', 'abb'] |
| | 匹配 | 左或 | 右的字符,re.search("abc|ABC","ABCBabcCD").group() 結(jié)果'ABC' |
(...) | 分組匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 結(jié)果'abcabca45' |
[...] | 匹配中括號(hào)中限定的字符集 |
\A | 只從字符開頭匹配,re.search("\Aabc","joveabc") 是匹配不到的,相當(dāng)于 re.match('abc',"joveabc") 或 ^ |
\Z | 匹配字符結(jié)尾,同 $? |
\d | 匹配數(shù)字 0-9 |
\D | 匹配非數(shù)字 |
\w | 匹配 [A-Za-z0-9] |
\W | 匹配非 [A-Za-z0-9] |
\s | 匹配空白字符、\t、\n、\r,re.search("\s+","ab\tc1\n3").group() 結(jié)果'\t' |
(?P<name>...) | 分組匹配 re.search("(?P<province>[0-9]{3})(?P<city>[0-9]{3})(?P<birthday>[0-9]{8})(?P<small_man>[0-9X]{5})",id_num).groupdict()),結(jié)果是個(gè)字典 |
2、.
演示代碼如下
import reprint(re.search(".ou", "zou").group()) # '.'默認(rèn)匹配除\n之外的任意一個(gè)字符,若指定flag DOTALL,則匹配任意字符,包括換行;使用 group() 能直接輸出匹配到的字符
print(re.search(".", "\n"))
代碼輸出如下:
3、^
演示代碼如下
import reprint(re.search("^jove", "jovemalsmlmalm0").group()) # '^'以什么什么開頭
print(re.search("^jove", "0jovejovejovejovejove"))
代碼輸出如下:
4、$
演示代碼如下
import reprint(re.search("jove$", "0jovejovejovejovejove").group()) # '$'以什么什么結(jié)尾
print(re.search("^jove$", "jove")) # '^$'這樣組合就相當(dāng)于把開頭和結(jié)尾定死了
print(re.search("jove$", "0jovejovejovejovejove0"))
代碼輸出如下:
5、*
演示代碼如下
import reprint(re.search("a*", "aaaaaaabbbabbb")) # 匹配*號(hào)前的字符0次或多次
print(re.search("a*", "bbbabbb")) # 從頭開始匹配如果開頭不是a的話就直接返''
print(re.search("a*", "bbbbbbbb")) # 就算沒有一個(gè)a的會(huì)返回''
代碼輸出如下:
6、+
演示代碼如下
import reprint(re.search("(ab)+", "bbbababb").group()) # 匹配+號(hào)前的字符1次或多次 ab+相當(dāng)于a匹配一次,b匹配多次
print(re.search("a+", "bbbbbbb"))
代碼輸出如下:
7、?
演示代碼如下
import reprint(re.search('a?', "aaaabbbbbbbb")) # 匹配?號(hào)前的字符1次或0次,一定要在開頭
print(re.search("a?", "bbbbaqsssss")) # 返回''
代碼輸出如下:
8、{m}
演示代碼如下
import reprint(re.search("a{3}", "bbbbbaaaabbbb")) # 匹配前一個(gè)字符m次
print(re.search("a{3}", "bbbbbbbbb"))
代碼輸出如下:
9、{n,m}
演示代碼如下
import reprint(re.search("a{3,5}", "bbbbaaaabbbbb")) # 匹配3-5次,少了或多了就會(huì)返回None
代碼輸出如下:
10、|
演示代碼如下
import reprint(re.search("abc|ABC", "ABCBabcCD")) # 匹配abc或ABC 返回第一個(gè)找到的值
print(re.search("abc|ABC", "cbaBCbcCD")) # 沒有則返回None
代碼輸出如下:
11、(...)
演示代碼如下
import reprint(re.search("(abc){2}a(123|45)", "abcabca123456")) # 分組匹配 (abc){2}a(123|45) --> 兩個(gè)abc a 123或45
print(re.search("(abc){2}a(123|45)", "aaaa")) # 沒有則返回None
代碼輸出如下:
12、[...]
演示代碼如下
import reprint(re.findall("[0-9]{11}","張小姐,聯(lián)系方式:13744234523"))
代碼輸出如下:
13、\A
演示代碼如下
import reprint(re.search("\Aabc", "abcasdq")) # 從頭開始匹配,相當(dāng)于re.match()
print(re.search("\Aabc", "aabcasdq"))
代碼輸出如下:
? ? ? ? 在輸出當(dāng)中我們可以看到來自 Python 的一個(gè)警告:SyntaxWarning: invalid escape sequence '\A',而且我們所需的輸出也是能正常顯示的,我們先來看看這個(gè)警告是什么意思。
????????SyntaxWarning: invalid escape sequence 是 Python 中語法警告的一種類型,它表示在字符串中使用了無效的轉(zhuǎn)義序列(escape sequence)。在 Python 中,轉(zhuǎn)義序列以反斜杠(\)開頭,并用于表示特殊字符,例如換行符(\n)、制表符(\t)等。但有的時(shí)候反斜杠后面跟著的字符不一定是有效的轉(zhuǎn)義序列,在上面的代碼中,字符串"\Aabc"中的反斜杠(\)被視為轉(zhuǎn)義序列的開始,然而在這種情況下,它并不是有效的轉(zhuǎn)義序列。因此,出現(xiàn)了 SyntaxWarning: invalid escape sequence 警告。
? ? ? ? 而我們應(yīng)該如何解決該問題呢?我們只需要在反斜杠(\)前再加多一個(gè)反斜杠就可以消除該警告了,代碼如下
import reprint(re.search("\\Aabc", "abcasdq")) # 從頭開始匹配,相當(dāng)于re.match()
print(re.search("\\Aabc", "aabcasdq"))
代碼輸出如下:
14、\Z
演示代碼如下
import reprint(re.search("\\Aabc\\Z", "abc")) # \Z是匹配結(jié)尾的 \Aabc\Z相當(dāng)于 ^anc$
代碼輸出如下:
15、\d
演示代碼如下
import reprint(re.search("\\d{3}", "aJk8m643KN26H")) # 匹配連續(xù)三個(gè)的數(shù)字
print(re.search("\\d+", "aJk8m643KN26H")) # 匹配一個(gè)或多個(gè)數(shù)字
代碼輸出如下:
16、\D
演示代碼如下
import reprint(re.search("\\D+", "aJk8m643KN26H")) # 匹配一個(gè)或者多個(gè)非數(shù)字
print(re.findall("\\D+", "aJk8m643KN26H")) # 所有非數(shù)字的匹配到都放到列表哪里
print(re.findall("\\D", "aJk8m643KN26H")) # 所有非數(shù)字的匹配到都放到列表哪里
代碼輸出如下:
17、\w
演示代碼如下
import reprint(re.search("[a-zA-Z0-9]", "H")) # [a-zA-Z0-9] 代表字母大小寫和數(shù)字都可以匹配到
print(re.search("[a-zA-Z]", "A"))
print(re.search("[a-z]", "A"))
print(re.search("[a-zA-Z0-9]{7}", "aJk8m64KN26H")) # 匹配多次print(re.findall("\\w+", "aJk)8m6=43KN-26H")) # 所有[a-zA-Z0-9]的匹配到都放到列表哪里
代碼輸出如下:
18、\W
演示代碼如下
import reprint(re.findall("\\W+", "aJk)8m6=43KN-26H")) # 所有非[a-zA-Z0-9]的匹配到都放到列表哪里
代碼輸出如下:
19、\s
演示代碼如下
import reprint(re.findall("\\s", "aJk)8\n\tm6=43\rKN-2\t6H"))
代碼輸出如下:
20、(?P<name>...)
演示代碼如下
import reid_num = "440682198702041121X"
print(re.findall("([0-9]{3})([0-9]{3})([0-9]{4})([0-9]{4})([0-9X]{5})", id_num))
print(re.search("([0-9]{3})([0-9]{3})([0-9]{4})([0-9]{4})([0-9X]{5})", id_num).groups()) # 分組匹配groups() --> 出來是個(gè)元組
print(re.search("(?P<province>[0-9]{3})(?P<city>[0-9]{3})(?P<birthday>[0-9]{8})(?P<small_man>[0-9X]{5})",id_num).groupdict()) # 分組匹配groupdict() --> 出來是個(gè)字典
代碼輸出如下:
? ? ? ? 到這里,常用的正則表達(dá)式已經(jīng)介紹完了,不過這只是正則表達(dá)式的冰山一角。單單是正則表達(dá)式的各種規(guī)則就可以寫一本四百多頁的書出來,如果還想了解更多請(qǐng)留言或者私信我來進(jìn)行交流。? ??
練習(xí)
一、題目
1、驗(yàn)證手機(jī)號(hào)是否合法
2、驗(yàn)證郵箱是否合法
3、開發(fā)一個(gè)簡(jiǎn)單的 Python 計(jì)算器,實(shí)現(xiàn)加減乘除及括號(hào)優(yōu)先級(jí)解析
- 用戶輸入 1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) 等類似公式
- 必須自己解析里面的 ()、+、-、*、/ 符號(hào)和公式(不能調(diào)用 eval 等類似功能實(shí)現(xiàn))
- 運(yùn)算后得出結(jié)果,結(jié)果必須與真實(shí)的計(jì)算器所得出的結(jié)果一致
提示:
re.search(r'\([^()]+\)',s).group()????????# 可拿到最里層的括號(hào)中的值
二、答案
1、驗(yàn)證手機(jī)號(hào)是否合法
import rewhile True:phone_number = input("Please input you phone number:")if re.search("^1[0-9]{10}",phone_number) is not None:print("ok,this is true number...")breakelse:print("sorry,this is bad number...\nplease retry input new phone number...")
2、驗(yàn)證郵箱是否合法
import rewhile True:mail = input("Please input you email:")if re.search("\\w+[@]\\w+\\.(com|cn|edu)", mail) is not None:print("ok,this is true email...")breakelse:print("sorry,this is bad email...\nplease retry input new email...")
3、開發(fā)一個(gè)簡(jiǎn)單的 Python 計(jì)算器,實(shí)現(xiàn)加減乘除及拓號(hào)優(yōu)先級(jí)解析
import rebracket = re.compile(r'\([^()]+\)') # 尋找最內(nèi)層括號(hào)規(guī)則
mul = re.compile(r'(\d+\.?\d*\*-\d+\.?\d*)|(\d+\.?\d*\*\d+\.?\d*)') # 尋找乘法運(yùn)算規(guī)則
div = re.compile(r'(\d+\.?\d*/-\d+\.?\d*)|(\d+\.?\d*/\d+\.?\d*)') # 尋找除法運(yùn)算規(guī)則
add = re.compile(r'(-?\d+\.?\d*\+-\d+\.?\d*)|(-?\d+\.?\d*\+\d+\.?\d*)') # 尋找加法運(yùn)算規(guī)則
sub = re.compile(r'(-?\d+\.?\d*--\d+\.?\d*)|(-?\d+\.?\d*-\d+\.?\d*)') # 尋找減法運(yùn)算規(guī)則
c_f = re.compile(r'\(?\+?-?\d+\)?') # 檢查括號(hào)內(nèi)是否運(yùn)算完畢規(guī)則
strip = re.compile(r'[^(].*[^)]') # 脫括號(hào)規(guī)則def Mul(s):"""計(jì)算表達(dá)式中的乘法運(yùn)算"""exp = re.split(r'\*', mul.search(s).group())return s.replace(mul.search(s).group(), str(float(exp[0]) * float(exp[1])))def Div(s):"""計(jì)算表達(dá)式中的除法運(yùn)算"""exp = re.split(r'/', div.search(s).group())return s.replace(div.search(s).group(), str(float(exp[0]) / float(exp[1])))def Add(s):"""計(jì)算表達(dá)式中的加法運(yùn)算"""exp = re.split(r'\+', add.search(s).group())return s.replace(add.search(s).group(), str(float(exp[0]) + float(exp[1])))def Sub(s):"""計(jì)算表達(dá)式中的減法運(yùn)算"""exp = sub.search(s).group()if exp.startswith('-'): #如果表達(dá)式形如:-2.2-1.2;需變換為:-(2.2+1.2)exp = exp.replace('-', '+') #將-號(hào)替換為+號(hào);+2.2+1.2res = Add(exp).replace('+', '-') #調(diào)用Add運(yùn)算,將返回值+3.4變?yōu)?3.4else:exp = re.split(r'-', exp)res = str(float(exp[0]) - float(exp[1]))return s.replace(sub.search(s).group(), res)def calc():while True:s = input('Please input the expression(q for quit):') # 例:'1+2- (3* 4-3/2+ ( 3-2*(3+ 5 -3* -0.2-3.3*2.2 -8.5/ 2.4 )+10) +10)'if s == 'q':breakelse:s = ''.join([x for x in re.split('\\s+', s)]) # 將表達(dá)式按空格分割并重組if not s.startswith('('): # 若用戶輸入的表達(dá)式首尾無括號(hào),則統(tǒng)一格式化為:(表達(dá)式)s = str('(%s)' % s)while bracket.search(s): # 若表達(dá)式s存在括號(hào)s = s.replace('--', '+') # 檢查表達(dá)式,并將--運(yùn)算替換為+運(yùn)算s_search = bracket.search(s).group() # 將最內(nèi)層括號(hào)及其內(nèi)容賦給變量s_searchif div.search(s_search): # 若除法運(yùn)算存在(必須放在乘法之前)s = s.replace(s_search, Div(s_search)) # 執(zhí)行除法運(yùn)算并將結(jié)果替換原表達(dá)式elif mul.search(s_search): # 若乘法運(yùn)算存在s = s.replace(s_search, Mul(s_search)) # 執(zhí)行乘法運(yùn)算并將結(jié)果替換原表達(dá)式elif sub.search(s_search): # 若減法運(yùn)算存在(必須放在加法之前)s = s.replace(s_search, Sub(s_search)) # 執(zhí)行減法運(yùn)算并將結(jié)果替換原表達(dá)式elif add.search(s_search): # 若加法運(yùn)算存在s = s.replace(s_search, Add(s_search)) # 執(zhí)行加法運(yùn)算并將結(jié)果替換原表達(dá)式elif c_f.search(s_search): # 若括號(hào)內(nèi)無任何運(yùn)算(類似(-2.32)除外)s = s.replace(s_search, strip.search(s_search).group()) # 將括號(hào)脫掉,例:(-2.32)---> -2.32print('The answer is: %.2f' % (float(s)))if __name__ == '__main__':calc()