【问题标题】:Restructure CSV data with Notepad++, Regex使用 Notepad++、Regex 重构 CSV 数据
【发布时间】:2021-02-24 01:37:14
【问题描述】:

我有一个包含以下标题和(示例)数据的 CSV 文件:

StopName,RouteName,Travel_Direction,Latitude,Longitude
StreetA @ StreetB,1 NameA,DirectionA,Lat,Long
StreetC @ StreetD,1 NameA,DirectionA,Lat,Long
...
StreetE @ StreetF,1 NameA,DirectionB,Lat,Long
StreetG @ StreetH,1 NameA,DirectionB,Lat,Long
...
StreetI @ StreetJ,2 NameB,DirectionC,Lat,Long
StreetK @ StreetL,2 NameB,DirectionC,Lat,Long
...
StreetM @ StreetN,2 NameB,DirectionD,Lat,Long
StreetO @ StreetP,2 NameB,DirectionD,Lat,Long
.
.
.

我想使用正则表达式(目前在 Notepad++ 中)得到以下结果:

1 NameA - DirectionA=[[StreetA @ StreetB,[Lat,Long]], [StreetC @ StreetD,[Lat,Long]], ...]
1 NameA - DirectionB=[[StreetD @ StreetE,[Lat,Long]], [StreetF @ StreetG,[Lat,Long]], ...]
2 NameB - DirectionC=[[StreetH @ StreetI,[Lat,Long]], [StreetJ @ StreetK,[Lat,Long]], ...]
2 NameB - DirectionD=[[StreetL @ StreetM,[Lat,Long]], [StreetN @ StreetO,[Lat,Long]], ...]
.
.
.

使用正则表达式和替换,

RgX: ^([^,]*),([^,]*),([^,]*),(.*)
Sub: $2 - $3=[$1,[\4]]

Demo: https://regex101.com/r/gS9hD6/1

我已经走到这一步了:

1 NameA - DirectionA=[StreetA @ StreetB,[Lat,Long]]
1 NameA - DirectionA=[StreetC @ StreetD,[Lat,Long]]
1 NameA - DirectionB=[StreetE @ StreetF,[Lat,Long]]
1 NameA - DirectionB=[StreetG @ StreetH,[Lat,Long]]
2 NameB - DirectionC=[StreetI @ StreetJ,[Lat,Long]]
2 NameB - DirectionC=[StreetK @ StreetL,[Lat,Long]]
2 NameB - DirectionD=[StreetM @ StreetN,[Lat,Long]]
2 NameB - DirectionD=[StreetO @ StreetP,[Lat,Long]]

在一个新的正则表达式中,我尝试将上述结果拆分为“=”,但不知道从那里去哪里。

我认为获得所需结果的一种方法是保留“=”之前的第一个唯一实例,用“,”替换新行并用 [..] 将其括起来以使其成为数组形式。

编辑: 大约有 10,000 个站点(总共),但只有大约 100 条独特的路线。

编辑 2:(也许我现在要求的更改太多)

对于第一个正则表达式:

  • 如果我想使用“\n”而不是“=”怎么办?

在第二次正则表达式替换开始时,

  • 如果我只有 RouteName 和 StopName 列,像这样:1 NameA - DirectionA=[StreetA @ StreetB, ...]
  • 同样,如果我只有 RouteName 和 Coordinates,像这样: 1 NameA - DirectionA=[[Lat,Long]]?

【问题讨论】:

  • 你不能只用正则表达式做进一步的部分。使用编程语言,它会让你的任务变得很容易。
  • @karthikmanchala 可以用 1 个正则表达式完成,多次应用 :-)
  • @Mariano 不,它不能,如果有动态数量的唯一键。在您的回答中,您假设只有 2 个键.. 可能是 3 个或更多... :) 检查this
  • @karthikmanchala 这就是你必须多次应用的地方(相同的正则表达式),在我的回答中描述为第 3 步。 check this
  • @Mariano 完全正确.. 如果我有 100 次出现怎么办?还是500? 1000?这就是programming languageeasy-to-do 发挥作用的地方.. :)

标签: regex notepad++


【解决方案1】:

步骤

1。第一次替换:

  • 查找内容:^([^,]*),([^,]*),([^,]*),(.*)
  • 替换为:\2 - \3=[[\1,[\4]]]
  • 全部替换

2。第二次替换:

  • 查找内容:^[\S\s]*?^([^][]*=)\[\[.*\]\]\K\]\R\1\[(.*)\]$
  • 替换为:, \2]
  • 全部替换

3。重复步骤2,直到不再出现。

  • 这意味着如果同一个键(Route - Direction 对)有 100 个实例(Stops),您将不得不点击 Replace All 7 次 (ceiling(log2(N)))。

说明

我在步骤 1 中修改了您的正则表达式,添加了一对额外的括号,将整个集合括起来。

对于第 2 步,它会为相同的 Direction 找到一对线,将最后一条附加到前一条。

^[\S\s]*?^([^][]*=)     #Group 1: captures "1 NameA - DirA="
\[\[.*\]\]              #matches the set of Stops - "[[StA @ StB,[Lat,Long]], ..."
\K                      #keeps the text matched so far out of the match
\]\R                    #closing "]" and newline
\1                      #match next line (if the same route)
\[(.*)\]$               #and capture the Stop (Group 2)

regex101 Demo for step 1
regex101 Demo for step 2

【讨论】:

  • +l 除非有很多实例要替换..这是一个非常好的答案!
  • 好收获!我修复了错误(它捕获的超出了应有的范围)。我还改进了正则表达式。一条有 100 个停靠点的路线现在需要在全部替换中单击 7 次。 regex101 demo
  • 太棒了!您可以添加另一个稍作更改的正则表达式...如果我想在第一个正则表达式中放入“\n”而不是“=”,它将如何更改第二个正则表达式?此外,正则表达式应该处理包含“-”本身的任何路由名称,对吗?
  • @Mariano 抱歉继续添加,但如果我在第二个正则表达式开头只有 2 列:1 NameA - DirectionA=[[StreetA @ StreetB]],我该如何应用相同的逻辑把这个数据加入所有的站点? (让我知道我是否应该将最后两个请求也放入 OP)
  • 您不能将\n 用作此正则表达式的键分隔符。这会使事情变得过于复杂。而且我认为两列并不重要。对其进行测试并编辑您需要的任何内容。如果它对你有用,请考虑接受这个答案。
【解决方案2】:

试试这个 我用手机记事本检查了一下,没有错误。

找到什么:

(s.+@\s\w+),(\d{1,} \w+),(\w+),(.+)

替换为:

\2 - \3=[[\1,[\4],...]]

【讨论】:

  • 感谢您的贡献。请编辑以包括解释。所以不鼓励只发代码的帖子。没有评论,正则表达式解决方案特别无用。随着未来的访问者学习一些适用于他们自己的编码问题的知识,高质量的答案会随着时间的推移而获得支持。另外,请查看降价。您可以通过缩进 4 个空格或使用 3 行反引号包装代码块来发布代码
  • 谢谢,如果可能的话,我需要一个视频来观看如何插入代码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 2012-10-16
相关资源
最近更新 更多