提供以下代码:
$2
我预计.*
会抓住我的最后一个括号,但我的输出是:
如果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;
}
}
默认情况下,为什么它停在支架上会贪婪?
答案 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调试器,以查看该模式与您的字符串的匹配情况。