我正在处理几个大型的fortran代码文件,遇到一个棘手的问题,我想将内嵌注释变成全行注释。逐行手动进行操作是荒谬的。带有感叹号!的所有字符(字符串中的除外)都是注释性的,并且会被编译器忽略。
也就是说改变
x = 9 !initialize x
到
x = 9
!initialize x
如果可以通过vim
或atom
来实现,那就太好了。
代码示例ex.f90
subroutine sample_photon(e0,zz,sgam,ierr)
use EBL_fit
use constants
use user_variables, only : ethr,model
use internal, only : debug
implicit none
integer ierr,nrej,nrejmax,nrenorm
real(kind=8) e0,zz,sgam,de,emin,emin0 &
,etrans1,etrans2,aw1,aw2,aw3,gb,gb0,gbmax,gbnorm,rrr,gnorm1,gnorm2,gnorm3
real(kind=8) psran,sigpair,w_EBL_density
de=4.d0*e0
emin0=ame**2/e0 ! minimal required energy for EBL photon
if (emin0.ge.eirmax) then ! wrong kinematics
!!! write(*,*)'photon:',emin0,eirmax,e0
ierr=1
return
end if
nrej=0
nrejmax=3000 ! user-defined limit on the N of rejections
nrenorm=0
gbmax=0.d0
gbnorm=2.5d0 ! normalization factor for rejection
etrans1=1.d-6 ! parameters for 'proposal function'
etrans2=eirmin*(1.d0+zz)**1.25
! partial weights for different energy intervals for 'proposal function
! sample emin (= sgam/de) according to the 'proposal function';
! define 'rejection function' ( gb = f(emin) / f_proposal(emin) )
sgam=emin*de ! c.m. energy for gamma-gamma interaction
gb=w_EBL_density(emin,zz)*sigpair(sgam)*emin/gb0
! if (gb.gt.1.d0.and.nrenorm.eq.0) write(*,*)'sample_cmb(photon): gb=' &
! ,gb,nrenorm,emin,emin0,emin0/etrans2 !/1.d3
if (psran().gt.gb) then ! rejection
nrej=nrej+1 ! total number of rejections for current sampling
gbmax=max(gbmax,gb) ! maximal value for rejection function
if(nrej.gt.nrejmax)then ! too many rejections
if(gbmax.le.0.d0)then ! wrong kinematics
write(*,*)'photon: gbmax=0!!!'
ierr=1
return
else
! write(*,*)'nrej(gamma)>nrejmax',nrej,emin0/etrans2,nrenorm,e0/1.d12,gbmax
gbnorm=gbnorm*gbmax*2.d0 ! change normalization for the rejection function
gbmax=0.d0
nrenorm=nrenorm+1
nrej=0
endif
endif
goto 1 ! new try
end if
end subroutine sample_photon
答案 0 :(得分:6)
让我们逐步构建它,并从简单的替换开始,在所有注释前缀序列(\r
)之前添加换行符(!
):
:%substitute/!\+.*$/\r&/
这留下了尾随空格。我们也可以匹配它,并使用捕获组(\(...\)
)作为实际注释。这将删除空格:
:%substitute/\s*\(!\+.*$\)/\r\1/
但是它仍然匹配行首的注释,并在前面添加了一个空行。我们可以添加一个后置断言,该行不能以!
开头,但是现在变得很丑陋:
:%substitute/^\%(^[^!].*\)\@=.*\zs\s*\(!\+.*$\)/\r\1/
相反,使用另一个Vim命令:global
(或其反向姐妹:vglobal
)更容易,以仅匹配不以!
开头的行,然后应用{{1 }}:
:substitute
最终要求是字符串中应保留感叹号。这将添加另一个正则表达式,并且将其集成到整体匹配中将非常困难,并且可能只能近似完成。幸运的是,通过突出显示语法,Vim已经知道什么是Fortran字符串!
我的PatternsOnText plugin有一个:%vglobal/^!/substitute/\s*\(!\+.*$\)/\r\1/
/ :SubstituteIf
组合(仅在条件为true / false时才可以进行替换)。它依赖的库提供了:SubstituteUnless
周围的包装器,可轻松为Fortran字符串定义谓词:
synIdAttr()
然后我们只需要用function! IsFortranString()
return ingo#syntaxitem#IsOnSyntax(getpos('.'), '^fortranString')
endfunction
+谓词替换:substitute
:
:SubstituteUnless
没有插件也可以实现相同的功能(使用:%vglobal/^!/SubstituteUnless/\s*\(!\+.*$\)/\r\1/ IsFortranString()
和:help sub-replace-special
/ synstack()
),但会更加复杂。