首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一个接一个接一个单词,直到另一个特定的词

一个接一个接一个单词,直到另一个特定的词
EN

Stack Overflow用户
提问于 2016-01-23 12:43:25
回答 3查看 128关注 0票数 1

我有一个文字记录的.txt文件,如下所示

代码语言:javascript
复制
MICHEAL: blablablabla.

further talk by Michael.

more talk by Michael.

VALERIE: blublublublu.

Valerie talks more.

MICHAEL: blibliblibli.

Michael talks again.

........

总之,这一模式将持续到4000行,而不仅仅是两位发言者,而是多达七位不同的发言者,所有的名字都是用大写字母书写的(如上面的例子)。对于某些文本挖掘,我需要按照以下方式重新排列这个.txt文件

  1. 加入一位发言者后面的一行--但只有那些仍然属于他的--这样上面的文件看起来就像这样: 迈可:布拉巴拉。迈克尔的进一步谈话。迈克尔的更多讲话。蓝。瓦莱丽谈得更多。迈克尔:天哪。迈克尔又开口了。
  2. 按字母顺序对.txt文件中现在正确连接的行进行排序,以便扬声器所讲的所有行现在都在一起。但是,排序功能不应该对一个说话人说的句子进行排序(在把每个说话人的话排在一起之后)。

我知道一些基本的vim命令,但还不足以解决这个问题。尤其是第一个。我不知道我能在vim中实现哪种模式,以便它只连接每一个发言者的线条。

任何帮助都会得到极大的帮助!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-23 13:54:39

好吧,首先答案是:

代码语言:javascript
复制
:g/^\u\+:/,/\n\u\+:\|\%$/join

现在的解释是:

  • g表示全局,并在匹配的每一行上执行以下命令
  • /^u+:/是模式:g搜索:^是行的开始,\u是大写字符,+<代码>E 216表示一个或多个匹配,E 117E 218毫不奇怪:
  • 然后是棘手的部分,我们使执行的命令成为一个范围,从匹配到其他模式匹配。/\n\u+:|\%$是由管道@分隔的两个部分。\n\u+:是一个新的行,后面跟着最后一个模式,即下一个说话人前面的行。\%$是文件的结尾
  • join做它在罐头上说的话

因此,把它放在一起:对于每一个发言者,加入到行之前的下一个发言者或文件的结尾。

我现在最接近的排序是

:排序/\u+:/ r

它只会按说话人的名字排序,并反转另一行,所以这并不是你想要的。

票数 3
EN

Stack Overflow用户

发布于 2016-01-23 13:41:42

嗯,我对vim不太了解,但我正准备匹配对应的特定扬声器的线条,这是regex

Regex: /([A-Z]+:)([A-Za-z\s\.]+)(?!\1)$/gm

解释:

([A-Z]+:)捕获扬声器的名称,其中只包含大写字母。

([A-Za-z\s\.]+)捕捉到了对话。

(?!\1)$反向引用议长的名字,并比较下一位发言者是否与上一位发言者相同。如果没有,则匹配,直到找到新的扬声器。

我希望这至少对你的匹配有所帮助。

票数 0
EN

Stack Overflow用户

发布于 2016-01-23 16:25:02

下面是解决您的问题的脚本解决方案。

它没有经过很好的测试,所以我添加了一些注释,这样您就可以轻松地修复它。

要使它运转,只需:

  • 在脚本顶部的g:speakers变量中填充所需的大写名称;
  • 源脚本(ex::sav /tmp/script.vim|so %);
  • 通过扬声器运行:call JoinAllSpeakLines()连接线路;
  • 运行:call SortSpeakLines()进行排序

您可以调整不同的模式以更好地满足您的需要,例如添加一些空间容限(\u\{2,}\s*\ze:)。

以下是代码:

代码语言:javascript
复制
" Fill the following array with all the speakers names:
let g:speakers = [ 'MICHAEL', 'VALERIE', 'MATHIEU' ]
call sort(g:speakers)


function! JoinAllSpeakLines()
" In the whole file, join all the lines between two uppercase speaker names 
" followed by ':', first inclusive:
    silent g/\u\{2,}:/call JoinSpeakLines__()
endf

function! SortSpeakLines()
" Sort the whole file by speaker, keeping the order for
" each speaker.
" Must be called after JoinAllSpeakLines().

    " Create a new dict, with one key for each speaker:
    let speakerlines = {}
    for speaker in g:speakers
        let speakerlines[speaker] = []
    endfor

    " For each line in the file:
    for line in getline(1,'$')
        let speaker = GetSpeaker__(line)
        if speaker == ''
            continue
        endif
        " Add the line to the right speaker:
        call add(speakerlines[speaker], line)
    endfor

    " Delete everything in the current buffer:
    normal gg"_dG

    " Add the sorted lines, speaker by speaker:
    for speaker in g:speakers
        call append(line('$'), speakerlines[speaker])
    endfor

    " Delete the first (empty) line in the buffer:
    normal gg"_dd
endf

function! GetOtherSpeakerPattern__(speaker)
" Returns a pattern which matches all speaker names, except the
" one given as a parameter.
    " Create an new list with a:speaker removed:
    let others = copy(g:speakers)
    let idx = index(others, a:speaker)
    if idx != -1
        call remove(others, idx)
    endif
    " Create and return the pattern list, which looks like
    " this : "\v<MICHAEL>|<VALERIE>..."
    call map(others, 'printf("<%s>:",v:val)')
    return '\v' . join(others, '|')
endf

function! GetSpeaker__(line)
" Returns the uppercase name followed by a ':' in a line
    return matchstr(a:line, '\u\{2,}\ze:')
endf

function! JoinSpeakLines__()
" When cursor is on a line with an uppercase name, join all the
" following lines until another uppercase name.
    let speaker = GetSpeaker__(getline('.'))
    if speaker == ''
        return
    endif
    normal V
    " Search for other names after the cursor line:
    let srch = search(GetOtherSpeakerPattern__(speaker), 'W')
    echo srch
    if srch == 0
        " For the last one only:
        normal GJ
    else
        normal kJ
    endif
endf
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34963609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档