我正在尝试使用正则表达式在同一行上进行多次搜索和替换。我相信 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
很简单,先把字符串拆分成行,再用逗号把每行拆分成list
。str
最后返回第一个元素和每个其他元素的组合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脚本还:
Plugins
->Plugins Admin...
-> 检查PythonScript
并点击Install
。Plugins
->PythonScript
->New Script
-> 在默认scripts
目录中创建它。- 添加这些内容并保存:
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-n
flag:将对输入的每一行进行循环,并执行为每一行提供的代码-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
当然芝加哥不是一个州:-)