Regex для добавления некоторых символов в определенной позиции - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть текстовый файл, который выглядит следующим образом:

abandon(icl>leave>do,agt>person,obj>person);CAT(CATV),AUX(AVOIR),VAL1(GN) ; 

Я хочу изменить его, используя регулярные выражения, так как это действительно длинный текст. Я хочу перед каждым CAT (...) и после первого ";"добавить первое слово каждой строки. Там должен быть также второй ";"после добавленного слова и перед CAT. Как я могу это сделать?

Итак, мой вывод будет:

abandon(icl>leave>do,agt>person,obj>person);abandon;CAT(CATV),AUX(AVOIR),VAL1(GN) ;

Ответы [ 4 ]

1 голос
/ 04 ноября 2019

Вы можете попробовать выполнить поиск и замену в режиме регулярных выражений:

Find:    ^([^(]+)(.*?;)(CAT.*)$
Replace: $1$2$1;$3

Идея состоит в том, чтобы просто разделить каждую строку на части, которые нам нужны, чтобы связать воедино замену. В этом случае первая группа захвата - это слово, которое мы планируем вставить после первой точки с запятой, перед CAT.

Демо

Только что заметил, что вы используете Python. Мы можем попробовать:

inp = """aarhus(iof>city>thing,equ>arhus);CAT(CATN),N(NP) ;
abadan(iof>city>thing);CAT(CATN),N(NP) ;
abandon(icl>leave>do,agt>person,obj>person);CAT(CATV),AUX(AVOIR),VAL1(GN) ;"""
output = re.sub(r'([^(]+)(.*?;)(CAT.*?;)\s*', '\\1\\2\\1;\\3\n', inp)
print(output)

Это печатает:

aarhus(iof>city>thing,equ>arhus);aarhus;CAT(CATN),N(NP) ;
abadan(iof>city>thing);abadan;CAT(CATN),N(NP) ;
abandon(icl>leave>do,agt>person,obj>person);abandon;CAT(CATV),AUX(AVOIR),VAL1(GN) ;
0 голосов
/ 04 ноября 2019

Этот скрипт читает входной файл, выполняет замену и записывает в выходной файл:

import re

infile = 'input.txt'
outfile = 'outfile.txt'
f = open(infile, 'r')
o = open(outfile, 'w')
for line in f:
    o.write(re.sub(r'((\w+).+?)(?=;CAT)', r'\1;\2', line))

cat outfile.txt 
aarhus(iof>city>thing,equ>arhus);aarhus;CAT(CATN),N(NP) ;
abadan(iof>city>thing);abadan;CAT(CATN),N(NP) ;
abandon(icl>leave>do,agt>person,obj>person);abandon;CAT(CATV),AUX(AVOIR),VAL1(GN) ; 
0 голосов
/ 04 ноября 2019

Совпадение разных групп и вязание может быть быстрее, чем заменить регулярное выражение. Придется проверить

import re

#=== DESIRED ===================================================================
# aarhus(iof>city>thing,equ>arhus);aarhus;CAT(CATN),N(NP) ;
# abadan(iof>city>thing);abadan;CAT(CATN),N(NP) ;
# abandon(icl>leave>do,agt>person,obj>person);abandon;CAT(CATV),AUX(AVOIR),VAL1(GN) ;```
#===============================================================================

data = ["abadan(iof>city>thing);CAT(CATN),N(NP) ;", 
"abandon(icl>leave>do,agt>person,obj>person);CAT(CATV),AUX(AVOIR),VAL1(GN) ;"]

# Matching different groups, and then stiching together may be faster tna a regex replace. 
# Basedon /3183589/regex-poka-no-ne-vklychaya
# (?:(?!CAT).)* - match anything until the start of the word CAT.
# I.e.
# (?:        # Match the following but do not capture it:
# (?!CAT)  # (first assert that it's not possible to match "CAT" here
#  .         # then match any character
# )*         # end of group, zero or more repetitions.
p = ''.join(["^", # Match start of string
             "(.*?(?:(?!\().)*)", # Match group one, anything up to first open paren, which will be the first word (I.e. abadan or abandon
             "(.*?(?:(?!CAT).)*)", # Group 2, match everything after group one, up to "CAT" but not including CAT
             "(.*$)" # Match the rest
             ])

for line in data:
    m = re.match(p, line)    
    newline  = m.group(1) # First word
    newline += m.group(2) # Group two
    newline += m.group(1) + ";" # First word again with semi-colon
    newline += m.group(3) # Group three

    print(newline)

ВЫХОД:

abadan(iof>city>thing);abadan;CAT(CATN),N(NP) ;
abandon(icl>leave>do,agt>person,obj>person);abandon;CAT(CATV),AUX(AVOIR),VAL1(GN) ;
0 голосов
/ 04 ноября 2019

В Python вы можете сделать это следующим образом:

import re

test_strings = [
    'aarhus(iof>city>thing,equ>arhus);CAT(CATN),N(NP) ;',
    'abadan(iof>city>thing);CAT(CATN),N(NP) ;',
    'abandon(icl>leave>do,agt>person,obj>person);CAT(CATV),AUX(AVOIR),VAL1(GN) ;' 
]
# first group matches the wordthat you want to repeat, then you capture the rest
# until the ;CAT which you capture separately
regex = r'(\w+)(.*)(;CAT.*)'

new_strings = []
for test_string in test_strings:
    match = re.match(regex, test_string)
    new_string = match.group(1) + match.group(2) + ";" + match.group(1) + match.group(3)
    new_strings.append(new_string)
    print(new_string)

Дает вам:

aarhus(iof>city>thing,equ>arhus);aarhus;CAT(CATN),N(NP) ;
abadan(iof>city>thing);abadan;CAT(CATN),N(NP) ;
abandon(icl>leave>do,agt>person,obj>person);abandon;CAT(CATV),AUX(AVOIR),VAL1(GN) ;

И ваши строки хранятся в списке new_strings.

РЕДАКТИРОВАТЬ: Чтобы прочитать ваш файл в виде списка строк, готовых для изменения, просто используйте оператор with open и выполните readlines():

my_file = 'my_text_file.txt'

with open(my_file, 'r') as f:
    my_file_as_list = f.readlines()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...