正则表达式在同一行上搜索/替换多次

正则表达式在同一行上搜索/替换多次

我正在尝试使用正则表达式在同一行上进行多次搜索和替换。我相信 Regex 可以使用正向前瞻/后瞻功能来做到这一点。

我有一长串州和各州机场的列表。我试图将它们成对地逐行排列 State, Aiport

这是输入

State, Airports
----------------
Chicago, ORD, MDW
NY, JFK, LGA, EWR
California, LAX, JWA, LGB, BUR

这是输出。

Chicago, ORD
Chicago, MDW  
NY, JFK
NY, LGA
NY, EWR
California, LAX
California, JWA
California, LGB
California, BUR

您能帮忙建议一个正则表达式或任何其他方法来实现这一点吗?谢谢。

我使用 Notepad++ 来进行正则表达式,但也可以为此使用任何文本编辑器。

答案1

  • Ctrl+H
  • 找什么:^(\w+,\h*)(\w+)(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?
  • 用。。。来代替:$1$2\n(?3$1$3)(?4\n$1$4)(?5\n$1$5)(?6\n$1$6)(?7\n$1$7)(?8\n$1$8)(?9\n$1$9)
  • 打钩 相符
  • 打钩 环绕
  • 选择 正则表达式
  • 取消勾选 . matches newline
  • Replace all

解释:

^               # beginning of line
    (               # group 1
        \w+             # 1 or more word characters
        ,               # a comma
        \h*             # 0 or more horizontal spaces
    )               # end group 1
    (\w+)           # group 2, 1 or more word characters
    (?:             # non capture group
        \h*             # 0 or more horizontal spaces
        (\w+)           # group 3, 1 or more word characters
    )?              # end group, optional
(?:,\h*(\w+))?      # same as above
(?:,\h*(\w+))?      # same as above
(?:,\h*(\w+))?      # same as above
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 

替代品:

$1              # content of group 1
$2              # content of group 2
\n              # line feed, you can use \r\n for Windows
(?3             # if group 3 exists
    $1              # content of group 1
    $3              # content of group 3
)               # endif
(?4\n$1$4)      # same as above
(?5\n$1$5)      # ...
(?6\n$1$6)      # ...
(?7\n$1$7)      # ...
(?8\n$1$8)      # ...
(?9\n$1$9)      # ...

截图(之前):

在此处输入图片描述

截图(之后):

在此处输入图片描述

答案2

这个正则表达式太复杂了。使用实际的编程语言,事情会简单得多。

这里我给出了一个 Python 示例。获取 Python这里

假设你有这样的输入:

Chicago, ORD, MDW
NY, JFK, LGA, EWR
California, LAX, JWA, LGB, BUR

并且您想将其转换为给定的输出:

Chicago, ORD
Chicago, MDW  
NY, JFK
NY, LGA
NY, EWR
California, LAX
California, JWA
California, LGB
California, BUR

很简单,先把字符串拆分成行,再用逗号把每行拆分成liststr最后返回第一个元素和每个其他元素的组合list

lines = """Chicago, ORD, MDW
NY, JFK, LGA, EWR
California, LAX, JWA, LGB, BUR"""

for line in lines.splitlines():
    lst = line.split(', ')
    first = lst[0]
    for e in lst[1:]:
        print(f'{first}, {e}')

答案3

对于 Notepad++,如果必须使用它,你可以使用Python脚本还:

  1. Plugins-> Plugins Admin...-> 检查PythonScript并点击Install
  2. Plugins-> PythonScript-> New Script-> 在默认scripts目录中创建它。
  3. 添加这些内容并保存:
import re

def split_text(match):
  # Split by comma and any number of horizontal whitespace
  parts = re.split(',[\t ]*', match.group(1))  
  results = []
  
  # Skip first item and create strings with all the combinations
  for part in parts[1:]:
    results.append("%s, %s"%(parts[0], part))
    
  # Combine all parts with separated by newline
  return "\n".join(results)

# Ensure proper matches and call split_text() handler function
# (?!\A) - don't match start of file (first line)
# [\w\t ,]+ - match only word characters, horizontal whitespace and commas
editor.rereplace('^(?!\A)([\w\t ,]+)$', split_text);

这与标题一起工作并将其保留。

答案4

我知道您要求在 Notepad++ 中使用正则表达式,但无论如何,这里有一个 perl 单行代码:

perl -nle '($state,@f) = split /,\s*/; print "$state, $_" for @f;' < txt

解释:

  • perl:调用 perl
  • -nflag:将对输入的每一行进行循环,并执行为每一行提供的代码
  • -l标志:自动删除输入的行尾并将其添加到输出
  • -e标志:使用提供的代码作为参数
  • ($state,@f) = split /,\s*/:在逗号所在的任意位置拆分行,以可选空格分隔,将第一个值放入 $state,其余放入数组@f
  • print "$state, $_" for @f:针对@f(每个机场)中的每个项目,打印一行,其中包含州和机场

选择:

perl -F',\s*' -le '$state = shift @F; print "$state, $_" for @F;' < txt
  • -F',\s*'标志:使用提供的分隔符正则表达式自动拆分,将结果存储在 中@F。暗示-n
  • $state = shift @F:从中删除第一项@F并将其存储在$state

当然芝加哥不是一个州:-)

相关内容