如何在R中使用strsplit拆分议会演讲文本,提取发言者与内容
问题描述
我有一段包含议会演讲的文本数据(示例如下),希望用strsplit函数生成包含每位发言者及其对应演讲内容的数据框,预期输出格式也已给出,但尝试的代码没有得到预期结果,请求帮助。我有可用的发言者列表,且是R语言新手。
示例文本数据
df <- "MEHMET ALİ ÇELEBİ (İzmir) – Teşekkürler Sayın Başkan. 26-30 Haziran Özel Güvenlik Görevlileri Haftası’ndayız, kutluyorum. Bugün ülkemizde 350 bini aşkın özel güvenlik görevlimiz esnek ve güvencesiz çalışmanın en ağır koşullarına muhataptır. Bir: Maaş, özlük hakları, çalışma şartları ve risk tazminatları iyileştirilmelidir. İki: Görev tanımı dışında çalıştırılmaları engellenmelidir. Üç: Yıpranma hakkı, ödüllendirme, şehit ve gazilik talepleri karşılanmalıdır. Dört: Onlara yönelik yeni bir işçi sağlığı ve iş güvenliği düzenlemesi yapılmalıdır. Beş: Adli vakalarda avukat desteği verilmelidir. Altı: Taşeronda değil, çalıştıkları kurum bünyesinde istihdam edilmelidirler. Yedi: Belediye şirketlerine geçen özel güvenliklerimizin iş kollarının belirsizliği giderilmelidir. “Özel güvenlik her yerde, görmezden gelme!” diyorum, yüce Meclisi saygıyla selamlıyorum. BAŞKAN – Sayın Sazak… METİN NURULLAH SAZAK (Eskişehir) – Teşekkürler Başkanım. Türk sinemasının değerli ismi, Eskişehirli hemşehrim Cüneyt Arkın’a Allah’tan rahmet; ailesine, sevenlerine sabırlar dilerim. Türk sinemasının başı sağ olsun. Cüneyt Arkın, oynamış olduğu filmlerde, Türk tarihinin önemli kahramanlarını gençliğe sevdirmiş; sadece sinemada değil, yaşadığı hayatta da duruşuyla takdir toplamıştır. Ruhu şad, mekânı cennet olsun. BAŞKAN – Sayın Aycan… SEFER AYCAN (Kahramanmaraş) – Sayın Başkan, şehirlerimiz büyümektedir; bu nedenle de yeni imar planlarına, imar bölgelerine ihtiyaç doğmaktadır. Sağlıklı şehirleşme, imar planı doğrultusunda alt yapısı tamamlanarak yeni imar bölgeleri oluşturmaktan geçmektedir; kentsel dönüşüm, sağlıklı şehirleşme ve güvenli bina için de buna ihtiyaç vardır. Şehrim Kahramanmaraş’ın merkezi de konut ihtiyacı açısından tıkanmıştır, yeni imar planına ihtiyacı vardır. Güneyi tarım arazileridir; buralara zarar vermemek, imara kapamak gerekmektedir. Diğer taraftan, eski mahallelerde kentsel dönüşüm zorunlu hâle gelmiştir; bu nedenle, eski mahallelerde, özellikle Dulkadiroğlu bölgesinde kentsel dönüşümün teşvik edilmesi, kart sayısının 2’den 4’e hatta 6 veya 8 katlara çıkarılması gerekmektedir. Kahramanmaraş’ta kentsel dönüşüm teşvik edilmelidir; böylece, yeniden şehirleşme sağlanmalıdır; böylece, şehrin merkezinde konut ihtiyacı karşılanmış olacaktır. Saygılarımla."
预期输出
# [Speaker] [text] # [1,] "MEHMET ALİ ÇELEBİ" "Teşekkürler Sayın Başkan. 26-30 Haziran..." # [2,] "METİN NURULLAH SAZAK" "Teşekkürler Başkanım. Türk sinemasının..." # [3,] "SEFER AYCAN" "Sayın Başkan, şehirlerimiz büyümektedir..."
尝试的代码(未得到预期结果)
pat <- r"{(?>=\p{Lu}+?\s?)+\(?\p{Lu}+\)?\K(:)|(?<!\w)(\s)(?=\p{Lu}{2,})}" tmp <- trimws(el(strsplit(df, pat, perl=TRUE)))[-1] res <- matrix(tmp, ncol=2, byrow=TRUE) res
解决方案
既然你已有发言者列表,我们可以利用它精准分割文本,避免复杂正则的匹配问题,以下是适合新手的实现步骤:
步骤1:定义发言者列表
假设你的发言者列表为:
speakers <- c("MEHMET ALİ ÇELEBİ", "METİN NURULLAH SAZAK", "SEFER AYCAN")
步骤2:构造分割正则表达式
匹配发言者名称 + (地区) – 的开头模式,作为分割标识:
# 为每个发言者生成匹配规则,例如 "MEHMET ALİ ÇELEBİ \\(.*?\\) – " split_pattern <- paste0("(?<=\\n|^)", speakers, " \\(.*?\\) – ", collapse = "|")
步骤3:分割文本并整理成数据框
# 分割文本,perl=TRUE 支持正向预查以保留分割逻辑 split_text <- strsplit(df, split_pattern, perl = TRUE)[[1]] # 移除开头的空字符串(因为文本从第一个发言者开始) split_text <- split_text[-1] # 生成最终数据框:替换换行符为空格,去除首尾多余空格 result_df <- data.frame( Speaker = speakers, Text = trimws(gsub("\\n+", " ", split_text)) ) # 查看结果 print(result_df)
无发言者列表的替代方案
如果需要临时从文本中提取发言者,可先用正则匹配:
# 提取所有符合格式的发言者名称 speakers_extracted <- stringr::str_extract_all(df, "^[A-ZÜİÖĞŞÇ\\s]+(?= \\(.*?\\) – )", simplify = TRUE)[,1] speakers_extracted <- trimws(speakers_extracted) # 之后重复步骤2-3即可
运行上述代码后,会得到符合预期的结构,Text列会将原文本的换行符替换为空格,保持内容连贯。
内容的提问来源于stack exchange,提问作者noetherlaw
相关产品推荐
相关产品推荐

