如何用正则表达式提取下文中自然灾害的次数?
欲提取的灾害类型:冷空气、沙尘天气、地震、地质灾害、火灾
2023-04-10 11:16 来源:救灾和物资保障司
近日,应急管理部会同工业和信息化部、自然资源部、住房城乡建设部、交通运输部、水利部、农业农村部、卫生健康委、统计局、气象局、粮食和储备局、林草局、中国红十字会总会、国铁集团等部门和单位,对2023年一季度全国自然灾害情况进行了会商分析。一季度,我国自然灾害以干旱、风雹、低温冷冻和雪灾为主,洪涝、地震、地质灾害、沙尘暴和森林草原火灾等也有不同程度发生。各种自然灾害共造成472.2万人次受灾,因灾死亡39人;倒塌房屋100余间,严重损坏房屋600余间,一般损坏房屋3.8万余间;农作物受灾面积289.8千公顷;直接经济损失25.5亿元。
一季度全国自然灾害主要特点有:
一、西南地区发生冬春连旱,旱情较往年同期偏重
今年以来,西南地区大部降水量较常年同期偏少2成以上,加上同期气温偏高,云贵川渝等地干旱快速发展,局地山丘区农业生产、城乡供水受到一定影响,人畜饮水出现困难。农作物受灾面积193千公顷,以油料作物、蔬菜和经济林果为主。因旱需生活救助97万人,饮水困难人口主要分布于中高海拔山区。3月中旬,四川、重庆、贵州等地均出现明显降水,干旱得到不同程度缓和。总体上,一季度旱情较往年同期偏重。
二、多地遭受低温冷冻和雪灾,西藏林芝雪崩造成重大人员伤亡
一季度,我国共发生12次冷空气过程,较常年同期略为偏多。其中,4次过程达寒潮级别。1月13–16日冷空气过程为全国型寒潮过程,受寒潮引发降温、雨雪影响,重庆、云南等多地遭受低温冷冻和雪灾,农作物受灾面积10.8千公顷。3月11–14日,河南大部地区气温骤降,部分地区降暴雪,造成经济林果作物冻伤减产,农业经济损失3.5亿元。总体上,与近5年同期均值相比,一季度低温冷冻和雪灾因灾直接经济损失明显偏轻。此外,1月17日,西藏林芝市派墨公路多雄拉隧道出口处发生雪崩,部分车辆和人员被埋,因灾死亡28人。
三、风雹灾害影响南方地区,北方局地突发沙尘暴
1–2月,全国未发生区域性强对流天气过程,云南、西藏等局地遭受风雹灾害。3月下旬,南方地区出现今年首次大范围强对流天气过程,江南、华南部分地区出现大风、冰雹、雷暴和短时强降雨,江西、福建等地3万余间房屋受损,部分农业大棚和蔬菜、经济作物受灾。一季度,我国出现6次沙尘天气过程,其中4次发生在3月份。3月19–23日,北方地区出现今年以来最强沙尘天气过程,内蒙古、北京、甘肃、新疆等10省(区、市)出现浮尘或扬沙,局地出现沙尘暴,对交通运输、城市运行、群众健康等产生不利影响。
四、西部地区发生中强地震,未造成较大损失
一季度,我国大陆地区共发生4级以上地震22次,其中6.0–6.9级1次,5.0–5.9级2次,主要集中在新疆、四川、西藏等地。其中,1月30日新疆沙雅6.1级地震和2月27日新疆温宿5.1级地震,震中均位于人口稀少地区,未造成较大灾害损失。1月26日四川泸定5.6级地震,未造成人员伤亡。
五、南方局地遭受洪涝灾害,中南地区地质灾害多发
3月20–25日,南方地区出现大范围强降雨过程,涉及范围广、持续时间长、累计雨量大,福建、湖南局地出现洪涝灾害。依据入汛标准,我国3月24日进入汛期,较多年平均入汛日期偏早8天。另据统计,一季度全国共发生地质灾害97起,以小型崩塌、地面塌陷为主。此外,3月16日黄河封冻河段全线开河,凌汛期历时108天,凌情总体平稳,未发生严重凌汛灾害损失。
六、森林草原火灾总体形势平稳
一季度,全国共发生森林火灾148起,因灾死亡2人,受害森林面积约794公顷。从时间看,3月份进入森林火灾高发期,发生森林火灾87起,占一季度发生起数的59%;从地域看,森林火灾多点散发、南北并重,主要发生在广西、湖北、贵州、河南、河北等地。发生草原火灾2起,甘肃、内蒙古各1起,受害草原面积约310公顷。
问题分析
1、描述灾害时,语句结构一般为:【数量词 + 灾害名称】或【灾害名称 + 数量词】,例如:“22场地震”、“地震22场”。
2、数词可能是 1 位数,也可能是多位数,例如:6、97、237。
3、量词不固定,可能是“次”、“起”、“场”……
4、灾害名称长度不固定,比如:“地震”有 2 个字符、“沙尘天气”有 4 个字符。
代码方案
运行结果:
代码讲解
1、import re :re 是 Python 中的一个用来解析正则表达式的包。
2、[冷空气 沙尘天气 地震 地质灾害 火灾] 表示匹配方括号内的任意 1 个字符;但由于灾害名称可能包含不止 1 个字符,比如“沙尘天气”有 4 个字符,因此需要在方括号后写一个 + 来表示匹配方括号内的任意 1 个或多个字符。
3、同理,我们把所有可能的量词放在一个方括号里,即 [次起场] ,表示匹配任意 1 个量词。
4、在正则表达式中,\d 表示任意 1 个数字;由于数词可能是多位数,因此需要在 \d 右边写一个 + 来表示匹配任意 1 个或多个数字,即 \d+ 。
5、用英文括号分别把 左数量词匹配式、灾害名称匹配式、右数量词匹配式 包起来,即:(左数量词匹配式)(灾害名称匹配式)(右数量词匹配式),表示将 1 个完整的描述语句拆成这 3 个部分。例如:把“22场地震22场”拆成“22场”、“地震”、“22场”;但由于左、右两个数量词不可能同时存在,要么只有左数量词,要么只有右数量词,因此需要分别在两个数量词匹配式的括号右边加上 1 个 ? ,表示“可有可无”,即:(左数量词匹配式)?(灾害名称匹配式)(右数量词匹配式)?,即:(\d+[次起场])?([冷空气 沙尘天气 地震 地质灾害 火灾]+)(\d+[次起场])? 。
6、由于 [冷空气 沙尘天气 地震 地质灾害 火灾]+ 可以匹配方括号内的任意 1 个或多个字符,因此也可能匹配出“冷气”、“天灾”这种不符合条件的名称,因此我们需要用 灾害名称 in items 来过滤出符合要求的灾害名称。
7、由于 ? 表示“可有可无”,但在一个正确的描述语句中必然会有1个数量词,因此我们需要用 左数量词 or 右数量词 来去除“左、右两个数量词都为空”的条目。
8、接着我们使用 re.findall('\d+', 数量词) 从数量词中提取出数词,并使用 int 函数将数词转化为 int 类型。