【问题标题】:Python/JS regex to match any number that is less than XPython/JS 正则表达式匹配任何小于 X 的数字
【发布时间】:2017-05-15 08:31:44
【问题描述】:

我在一个文本文件中有一些 JSON 数据,例如:

..."priority":1,...
..."priority":3,...
..."priority":5,...

我要做的是匹配优先级小于或等于3的所有行。

所以匹配将是:

..."priority":1,...
..."priority":3,...

所以我的基本正则表达式可能如下所示:

/"priority":[0-9],/

还有一个简单的脚本来测试这个

const regex = /"priority":[0-9],/;

const str = '{"dateCreated":"2016-12-31T06:41:32.298Z","pid":15154,"count":1,"uid":"77d55631-36ab-4805-aa17-1c984c8d4d04","priority":1,"isRead":false,"line":"foo bar baz"}';

console.log(regex.test(str));   // true

所以这将匹配任何数字 0-9,但我如何匹配 X 及以下?其中 X 可能是 2 位数字?

这是一种简洁的方式吗?

文件中的原始数据如下所示:

{"dateCreated":"2016-12-31T20:31:42.928Z","pid":5502,"count":0,"uid":"b21ac5eb-e25f-411c-80e9-955ff6eab964","priority":2,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:43.058Z","pid":5502,"count":1,"uid":"19f69863-7bf7-45f1-99b8-30fe332e88b9","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:43.262Z","pid":5502,"count":2,"uid":"ee8ca050-d1b5-4787-8d9f-78b17a9c4e9e","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:43.462Z","pid":5502,"count":3,"uid":"40fdbf37-0caf-4dde-b6fa-8522cd333b6e","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:43.666Z","pid":5502,"count":4,"uid":"d1928b11-e93c-413a-8e4e-49ac8a7b38b5","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:43.865Z","pid":5502,"count":5,"uid":"9fdff4bc-5126-43f9-85c6-d1212bac777b","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:44.071Z","pid":5502,"count":6,"uid":"3058cc78-eea6-4de9-96de-69c107b73724","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:44.271Z","pid":5502,"count":7,"uid":"52899ff3-2c17-4392-9409-a24152d4d15c","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:44.468Z","pid":5502,"count":8,"uid":"a775cd96-be9e-4713-83d3-92441d73443d","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:44.675Z","pid":5502,"count":9,"uid":"4fedb82b-1fb9-4049-870e-ff3bdf32fd5e","priority":2,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:44.877Z","pid":5502,"count":10,"uid":"c3fd144c-0182-4777-80a8-ce5db0da6525","priority":2,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:45.075Z","pid":5502,"count":11,"uid":"70fde6ea-f57c-4d2c-9eb0-d2b04fae23f2","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:45.277Z","pid":5502,"count":12,"uid":"540db3c7-bfe0-4d09-b4b6-d8922455c8d5","priority":3,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:45.483Z","pid":5502,"count":13,"uid":"1eca7c3b-be01-4457-885f-b7cb807952aa","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:45.683Z","pid":5502,"count":14,"uid":"d7f3cf02-e302-49d5-9977-fac592349335","priority":1,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:45.881Z","pid":5502,"count":15,"uid":"8760aa12-5c10-456f-8ae1-b570bc939ff7","priority":2,"isRead":false,"line":"foo bar baz"}
{"dateCreated":"2016-12-31T20:31:46.087Z","pid":5502,"count":16,"uid":"152a51da-d253-4245-999d-6518318c305d","priority":1,"isRead":false,"line":"foo bar baz"}

(它是换行分隔的 JSON 数据)

【问题讨论】:

  • 试过这个吗? [0-3][0-9]?
  • 通过您的实现,您是否可以简单地使用 /"priority":(\d+)/ 然后丢弃所有匹配 int(match_object.group(1)) >= X 的地方?
  • 正则表达式对于这项工作来说是一个糟糕的工具。如果X 是一个带有数字YZ 的数字,那么您要查找的表达式类似于r"\d|[0-%d]\d|%d[0-%d]" % (Y-1,Y,Z)
  • 正则表达式用于匹配字符串模式,它并不真正理解数字,而是代表该数字的字符,然后仅在 0-9 之间。
  • 有什么原因你不想json.loads 文本然后在结果数据结构上使用filter

标签: javascript python regex


【解决方案1】:

这对regex 来说不是一个好案例。相反,您应该使用 json 模块加载文件,然后简单地测试“priority”的值。

import json

with open('./sample_json.json', 'r') as json_data_file:
    json_data = json_data_file.readlines()
json_data_file.closed

使用列表推导,我们创建了一个 dicts 列表,json_data 中的每一行对应一个:

json_array = [json.loads(line) for line in json_data]

最后,我们对json_array 中的每个dict 运行大于小于测试并打印每个结果: for line in json_array:

    if line['priority'] < 20:
        print("Success!")

请注意,我们可以通过使用 for 循环而不是列表推导来完成此操作,结果相同:

json_array = []
for line in json_data:
    json_array.append(json.loads(line))

要了解有关 json 模块的更多信息,请在此处阅读:

https://docs.python.org/3/library/json.html


为了方便复制/粘贴,这里是不间断的代码:


import json

with open('./sample_json.json', 'r') as json_data_file:
    json_data = json_data_file.readlines()
json_data_file.closed

# Using list comprehension to populate json_array
json_array = [json.loads(line) for line in json_data]

# Using for loop to populate json_array
json_array = []
for line in json_data:
    json_array.append(json.loads(line))

for line in json_array:
    if line['priority'] < 20:
        print("Success!")

请注意,使用解析为 dict 的 JSON,您可以访问 JSON 每一行的任何键:

for item in json_array:
    for key in item.keys():
        print("KEY:", key, "VALUE:", json_array[0][key])
    print()

【讨论】:

  • 嗯,在这种情况下,每一行都是一个JSON,但是整个文件不能作为一个整体读取和解析。只有行可以单独解析。将其视为以 JSON 数据作为原始数据的日志文件。不过是的,还是把每一行解析成json,然后看数据,比用regex好,同意
  • 您能否在文件中添加一段显示 JSON 之前和之后的结构?
  • 优秀。谢谢。
  • 据我所知,使用正则表达式实际上可能比 JSON 解析更高效,尽管我不知道这一点。另外,我可能最终会用 C 来编写它,在这种情况下,使用正则表达式可能比在 C 中解析 JSON 更容易,不知道?
  • 测试这两种方法很容易,但这将是不同问题的一个很好的候选者。就 C 实现而言,世界上也有几个 JSON 库。例如digip.org/janssonbitbucket.org/yarosla/nxjsongithub.com/DaveGamble/cJSON
【解决方案2】:

使用 JSON 加载/解析等绝对是正确的方法,但就使用正则表达式解决这个问题而言

蛮力法,像这样:

"\"priority\":(1|2|3|4),"

对于较小的整数应该可以正常工作,并且可能非常不容易出错。

【讨论】:

    猜你喜欢
    • 2020-12-01
    • 2017-09-21
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    相关资源
    最近更新 更多