Python 如何限制正则表达式结果?

Python 如何限制正则表达式结果?,python,regex,Python,Regex,我试图从一个巨大的JSON文件中提取推文,我的正则表达式生成了太多的数据,我一辈子都不知道如何限制它。正则表达式找到了它的目的,但它也标记了太多 我正在使用的正则表达式如下所示(可能比需要的复杂,但我不想在这里修复): 下面是JSON文件中的截断行,它生成了太多的数据,例如: {"contributors": null, "truncated": false, "text": "RT @BelloPromotions: Myke Towers Ft. Mariah - Desaparecemos

我试图从一个巨大的JSON文件中提取推文,我的正则表达式生成了太多的数据,我一辈子都不知道如何限制它。正则表达式找到了它的目的,但它也标记了太多

我正在使用的正则表达式如下所示(可能比需要的复杂,但我不想在这里修复):

下面是JSON文件中的截断行,它生成了太多的数据,例如:

{"contributors": null, "truncated": false, "text": "RT @BelloPromotions: Myke Towers Ft. Mariah - Desaparecemos\n@myketowers #myketowers #mariah @mariah #Desaparecemos #music #musica #musicanu\u2026", "is_quote_status": false, "in_reply_to_status_id": null, "id": 1099558111000506369, "favorite_count": 0, "entities": {"symbols": [], "user_mentions": [{"id": 943461023293542400, "indices": [3, 19], "id_str": "943461023293542400", "screen_name": "BelloPromotions", "name": "Bello Promotions \ud83d\udcc8\ud83d\udcb0"}, {"id": 729572008909000704, "indices": [60, 71], "id_str": "729572008909000704", "screen_name": "MykeTowers", "name": "Towers Myke"}, {"id": 775866464, "indices": [92, 99], "id_str": "775866464", "screen_name": "mariah", "name": "Kenzie peretti"}], "hashtags": [{"indices": [72, 83], "text": "myketowers"}, {"indices": [84, 91], "text": "mariah"}, {"indices": [100, 114], "text": "Desaparecemos"}, {"indices": [115, 121], "text": "music"}, {"indices": [122, 129], "text": "musica"}], "urls": []}, "retweeted": false, "coordinates": null, "source": "<a href=\"http://twitter-dummy-auth.herokuapp.com/\" rel=\"nofollow\">Music Twr Suggesting</a>", "in_reply_to_screen_name": null, "in_reply_to_user_id": null, "retweet_count": 18, "id_str": "1099558111000506369", "favorited": false, "retweeted_status": {"contributors": null, "truncated": true, "text": "Myke Towers Ft. Mariah - Desaparecemos\n@myketowers #myketowers #mariah @mariah #Desaparecemos #music #musica\u2026 [link]", .......
如上所述,发布的JSON行的正则表达式的预期输出为:

Myke Towers Ft. Mariah - Desaparecemos\n@myketowers #myketowers #mariah @mariah #Desaparecemos #music #musica\u2026 [link]
最终写入我的文本文件的是:

myketowers
Myke Towers Ft. Mariah - Desaparecemos\n@myketowers #myketowers #mariah @mariah #Desaparecemos #music #musica\u2026 [link]
如何限制正则表达式结果

在我简单回答这个问题之前,我应该澄清为什么当前表达式会产生一个不想要的结果:在子表达式
(?:“contributors”:.*?,“truncated”:.*?,“text”:”)
中,最后一个
*?
,尽管它不贪婪,但与所有输入匹配

false, "text": "RT @BelloPromotions: Myke Towers Ft. Mariah - Desaparecemos\n@myketowers #myketowers #mariah @mariah #Desaparecemos #music #musica #musicanu\u2026", "is_quote_status": false, "in_reply_to_status_id": null, "id": 1099558111000506369, "favorite_count": 0, "entities": {"symbols": [], "user_mentions": [{"id": 943461023293542400, "indices": [3, 19], "id_str": "943461023293542400", "screen_name": "BelloPromotions", "name": "Bello Promotions \ud83d\udcc8\ud83d\udcb0"}, {"id": 729572008909000704, "indices": [60, 71], "id_str": "729572008909000704", "screen_name": "MykeTowers", "name": "Towers Myke"}, {"id": 775866464, "indices": [92, 99], "id_str": "775866464", "screen_name": "mariah", "name": "Kenzie peretti"}], "hashtags": [{"indices": [72, 83]
i、 e.第一个
“截断”之后的所有内容:
直到下一个
,“文本”:
,它不会被下面的
“RT…”排除,即不需要的
“myketowers”
之前的内容

因此,为了阻止表达式匹配所有输入,我们不能简单地允许每个字符(
)在
“截断的”:
,“文本”:
,而只能是那些构成可能值的字符
false
true
,或者为了简单起见,只能是单词字符(
\w
);因此,将上述子表达式更改为
(?:“参与者”:....,“被截断的”:\w*,“文本”:”)

如何限制正则表达式结果

在我简单回答这个问题之前,我应该澄清为什么当前表达式会产生一个不想要的结果:在子表达式
(?:“contributors”:.*?,“truncated”:.*?,“text”:”)
中,最后一个
*?
,尽管它不贪婪,但与所有输入匹配

false, "text": "RT @BelloPromotions: Myke Towers Ft. Mariah - Desaparecemos\n@myketowers #myketowers #mariah @mariah #Desaparecemos #music #musica #musicanu\u2026", "is_quote_status": false, "in_reply_to_status_id": null, "id": 1099558111000506369, "favorite_count": 0, "entities": {"symbols": [], "user_mentions": [{"id": 943461023293542400, "indices": [3, 19], "id_str": "943461023293542400", "screen_name": "BelloPromotions", "name": "Bello Promotions \ud83d\udcc8\ud83d\udcb0"}, {"id": 729572008909000704, "indices": [60, 71], "id_str": "729572008909000704", "screen_name": "MykeTowers", "name": "Towers Myke"}, {"id": 775866464, "indices": [92, 99], "id_str": "775866464", "screen_name": "mariah", "name": "Kenzie peretti"}], "hashtags": [{"indices": [72, 83]
i、 e.第一个
“截断”之后的所有内容:
直到下一个
,“文本”:
,它不会被下面的
“RT…”排除,即不需要的
“myketowers”
之前的内容


因此,为了阻止表达式匹配所有输入,我们不能简单地允许每个字符(
)在
“截断的”:
,“文本”:
,而只能是那些构成可能值的字符
false
true
,或者为了简单起见,只能是单词字符(
\w
);因此,将上述子表达式更改为
(?:“contributors”:..*,“truncated”:\w*,“text”:”)

就如其他人在注释中所述,您可能应该使用JSON解析器并从中获取它

然而,如果您的输入不是JSON(或者一次性将其全部拉入内存是不可行的),那么您应该对正则表达式进行一些调整

首先(也是同样,正如其他人已经指出的),
*?
只是“非贪婪”的意思,即它将找到最短的匹配;如果有匹配,它仍然会找到匹配。我猜您可以将其调整为

(?:[^"\\]+\\.)*)[^"\\]*
仅获取不包含未转换双引号的字符串

第二,我猜您希望
[^R][^T]
会跳过开头包含
RT
的匹配;但这不是它的意思。它会跳过包含一个非R字符后跟一个非T字符的匹配。因此它也不会匹配
at
Re

在Python(通常与PCRE兼容)正则表达式中,表示“必须不匹配”的方式是一种消极的前瞻
(?!RT)

把这一切放在一起,试试看

pattern = re.compile(r'(?:"contributors": "(?:[^"\\]+\\.)*)[^"\\]*",'
    r' "truncated": "(?:[^"\\]+\\.)*)[^"\\]*",'
    r' "text": ")((?!RT)(?:[^"\\]+\\.)*)[^"\\]*)"')

请理解,我不得不在这里的几个地方猜测或阅读字里行间的信息。如果你能更新你的问题,准确地解释你的数据是什么样的,以及你希望逻辑应该如何工作,这可能会得到改进,或者至少是调整,以达到你真正想要的效果。

正如其他人在评论中所评论的那样,你应该支持bably可能会使用JSON解析器,并从中获取它

然而,如果您的输入不是JSON(或者一次性将其全部拉入内存是不可行的),那么您应该对正则表达式进行一些调整

首先(也是同样,正如其他人已经指出的),
*?
只是“非贪婪”的意思,即它将找到最短的匹配;如果有匹配,它仍然会找到匹配。我猜您可以将其调整为

(?:[^"\\]+\\.)*)[^"\\]*
仅获取不包含未转换双引号的字符串

第二,我猜您希望
[^R][^T]
会跳过开头包含
RT
的匹配;但这不是它的意思。它会跳过包含一个非R字符后跟一个非T字符的匹配。因此它也不会匹配
at
Re

在Python(通常与PCRE兼容)正则表达式中,表示“必须不匹配”的方式是一种消极的前瞻
(?!RT)

把这一切放在一起,试试看

pattern = re.compile(r'(?:"contributors": "(?:[^"\\]+\\.)*)[^"\\]*",'
    r' "truncated": "(?:[^"\\]+\\.)*)[^"\\]*",'
    r' "text": ")((?!RT)(?:[^"\\]+\\.)*)[^"\\]*)"')

请理解,我不得不在这里的几个地方猜测或阅读字里行间的内容。如果你能更新你的问题,准确地解释你的数据是什么样子,以及你希望逻辑应该如何工作,这可能会得到改进,或者至少可以调整,以达到你真正想要的效果。

当我尝试时,正则表达式似乎找不到任何垫子你的输出看起来像是嵌套的组,但是我不能用正则表达式来复制它。我不会使用正则表达式。考虑你的巨大文件无限:一个流。现在你可以把你的文件解析成JSON流。我已经在C语言中这样做了,但是Python也应该有可用的答案。从这里开始:好POIN。t:如果你确实有结构良好的JSON数据,为什么要使用正则表达式呢?只需使用
JSON
加载文件并获取内容即可