Perl贪婪的正则表达式并不贪婪

时间:2016-07-26 08:05:42

标签: regex perl

提供以下代码:

$2

我预计.*会抓住我的最后一个括号,但我的输出是:
enter image description here
如果public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { PackageManager packageManager; ListView apkList,l; ImageView i; int c=0,sys=1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); Intent i1 = new Intent(MainActivity.this, SecondActivity.class); startActivity(i1); } }); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); FragmentManager fm=getFragmentManager(); FragmentTransaction ft=fm.beginTransaction(); Fragment1 f1=new Fragment1(); Fragment2 f2=new Fragment2(); ft.replace(R.id.fragment_2,f2); ft.replace(R.id.fragment_1,f1); ft.commit(); } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify img parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. int id = item.getItemId(); if (id == R.id.themes) { Intent i1=new Intent(MainActivity.this,SettingsActivity.class); startActivity(i1); } else if (id == R.id.settings) { Intent i1=new Intent(MainActivity.this,SettingsActivity.class); startActivity(i1); } else if (id == R.id.share) { } else if (id == R.id.send) { } else if (id == R.id.rating) { } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } } 默认情况下,为什么它停在支架上会贪婪?

1 个答案:

答案 0 :(得分:4)

.*是一个贪婪的子模式,但它不考虑分组。分组由一对未转义的括号定义(参见Use Parentheses for Grouping and Capturing)。

查看组边界的位置:

s/(.*?)\((.*)\)/$2/
  | G1|  |G2| 

因此,\(\)匹配()在之外是,并且不会成为{{}的一部分1}}也不$1

如果您需要$2成为)的一部分,请使用

$2

正则表达式引擎正在从左到右处理字符串和模式。首先处理第一个s/(.*?)\((.*\))/$2/ ^ ,它与第一个文字(.*?)符号匹配,因为它是懒惰的(在它返回有效匹配之前匹配尽可能少的字符),以及之前的整个部分(被放入第1组堆栈。然后,(匹配,但未捕获,则(匹配除换行符之前的任何0+字符,直到最后(.*)符号,并将捕获放入第2组。然后,)刚刚匹配。关键是)将整个字符串抓取到最后,但随后发生回溯,因为引擎试图适应模式中的最终.*)必须匹配,但不会在您的模式中捕获,因此,由于组边界放置,它不属于第2组。您可以在this regex demo page查看 regex调试器,以查看该模式与您的字符串的匹配情况。