如何重建正则表达式匹配的部分

时间:2018-12-29 06:03:49

标签: regex perl

例如,我在文本中简化了一些乳胶数学公式

public void location_request()
{
    final LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);
    builder.setAlwaysShow(true);
    GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(MainActivity.this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    mGoogleApiClient.connect();
    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            final LocationSettingsStates state = result.getLocationSettingsStates();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                   //The client can initialize location
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied.
                    try {

                        status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);

                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    break;
            }
        }
    });
}

我想将其转换为

This is ${\text{BaFe}}_{2}{\text{As}}_{2}$ crystal

这是仅将最内括号内的内容连接起来。

我发现我可以使用正则表达式模式

This is BaFe2As2 crystal

匹配最里面的括号。但是问题是如何将它们连接在一起?

我不知道这是否可以在notepad ++正则表达式替换中完成。如果不能使用notepad ++,我也可以接受perl一线解决方案。

2 个答案:

答案 0 :(得分:2)

在文档中可能显然存在多个这样的等式(两个$之间的标记)。因此,尽管您需要在所有{}之间汇编文本,但也需要将其约束在$对中。然后需要处理所有这些方程。

以单个模式匹配将导致相当复杂的正则表达式。相反,我们可以首先提取一对$中的所有内容,然后从中收集{} s中的文本,从而大大简化了正则表达式。这使每个方程式经过两次传递,但是出于计算目的,LaTex文档很小,并且效率降低是不明显的。

use warnings;
use strict;
use feature 'say';

my $text = q(This is ${\text{BaFe}}_{2}{\text{As}}_{2}$ crystal,)
         . q( and ${\text{Some}}{\mathbf{More}}$ text);

my @results;

while ($text =~ /\$(.*?)\$/g) { 
    my $eq = $1; 
    push @results, join('', $eq =~ /\{([^{}]+)\}/g);
} 

say for @results;

这将打印BaFe2As2SomeMore行。

处于while条件的正则表达式捕获两个$之间的所有字符。循环主体执行并再次检查条件后,正则表达式将从上一个匹配项的位置继续搜索字符串。这是由于标量modifier /g中的“全局” context,在这里由循环条件施加在正则表达式上。一旦没有更多匹配,则循环终止。

在主体中,我们在{}之间进行匹配,并且再次由于/g而对方程中的所有{}完成了匹配。但是,这里的正则表达式位于列表上下文中(因为它已分配给数组),然后/g使其返回所有匹配项。它们被连接成一个字符串,并添加到数组中。

为了替换处理后的方程式,请在替换中使用

$text =~ s{ \$(.*?)\$ }{ join('', $1 =~ /\{([^{}]+)\}/g) }egx;

其中修饰符e使之生效,以便将替换零件评估为Perl代码,其结果用于替换匹配的零件。然后,可以在其中运行正则表达式以匹配所有{}的内容,并将其连接到字符串中,如上所述。我使用s{}{}分隔符和x修饰符,以便也可以在匹配的部分中隔开内容。

由于整个替换都具有g修饰符,因此只要有匹配的方程式,正则表达式就会一直通过$text进行替换。

我使用问题中的硬编码字符串(扩展名)进行了简单演示。实际上,您会将文件读入标量变量(将其“粘贴”)并进行处理。

这取决于问题的前提,即方程式中感兴趣的文本清晰地位于{}之间。


缺少寻求单线的部分

perl -0777 -wnE'say join("", $1=~/\{([^{}]+)\}/g) while /\$(.*?)\$/g' file.tex

使用-0777会完整读取文件(“草木”),并且由于-n提供了输入行循环,因此文件位于$_变量中; while条件下的正则表达式默认在$_上有效。在while的每个交互中,$1中捕获的方程的内容直接匹配{} s。

然后替换每个方程式并打印出整个处理过的文件

perl -0777 -wne's{\$(.*?)\$}{join "", $1=~/\{([^{}]+)\}/g}eg; print' file.tex

我在join上删除了多余的空格和(不必要的)括号。

答案 1 :(得分:1)

在Notepad ++中使用此正则表达式。我试图匹配最里面的花括号之间不存在的所有内容,然后将匹配项替换为空白字符串。

[^{}]*\{|\}[^{}]*

Click for Demo

说明:

  • [^{}]*\{-匹配0+次出现的既不是{也不是}的任何字符,后跟{
  • |-或
  • \}[^{}]*-匹配},然后匹配0+次出现的既不是{也不是}的字符

更换前:

enter image description here

更换后:

enter image description here

更新:

尝试此更新的正则表达式:

\$?(?=[^$]*\$[^$]*$)(?:[^{}]*{|}[^{}]*)(?=[^$]*\$[^$]*$)\$?

Click for Demo