正则表达式:如何匹配所有字符,直到下次匹配?

时间:2019-04-20 16:48:23

标签: regex regex-negation regex-lookarounds

我有一个像这样的字符串:

Hello [@foo] how are you [@bar] more text

最终,我需要修改匹配/\[@.+?\]/的子字符串的每个实例,但是我还需要修改[@foo][@bar]之前/之后的每个子字符串。

以下正则表达式匹配[@.+]之前的子字符串,[@.+]本身,然后匹配[@.+]之后的子字符串,直到下一个字符后跟另一个[@.+]。 / p>

(.*?)(\[(@.+?)\])((.(?!(\[@.+?\])))*)

因此,第一个匹配项是“你好[@foo]你好吗?”,第二个匹配项是“ [@bar]更多文本”。

请注意第二场比赛开始时的空格。那就是问题所在。有没有办法使第一个匹配项包括所有字符,直到下一个[@.+]

我的正则表达式包含[@.+]实例之后[@.+]后面的字符,直到我们看到我无法看到使其包含所有字符的任何方法实际上位于[@.+]的另一个实例中。

我真的很想知道我是否缺少某些东西-确实感觉应该有一种更简单的方法来捕获给定比赛周围的字符,或者是一种更简单的方法来捕获不属于比赛的字符...

4 个答案:

答案 0 :(得分:3)

您有此正则表达式:

(.*?)(\[(@.+?)\])((.(?!(\[@.+?\])))*)
                   ^

看看那个点。它先于否定的前瞻。仅当满足负前瞻时,它才匹配数据单位。如果负前瞻失败,则点将不匹配。这发生在匹配\[@.+?\]之前的字符处。因此,不包含空格字符。

要包含它,您只需更改顺序即可。在负向前行传递之后放置点:

(.*?)(\[(@.+?)\])(((?!(\[@.+?\])).)*)
                                 ^

请参见live demo here

答案 1 :(得分:1)

如果我的理解正确,您希望将文本分成几组,每组都有一个[@.+]实例,并且所有文本都必须匹配成组。

尝试(?:^.*?)?\[@.+?\].*?(?=\[|$)

答案 2 :(得分:0)

This RegEx可能会帮助您获取这些变量。

[A-Za-z0-9]

您还可以将其他任何字符添加到`[A-Za-z0-9\.\+\@]` 中,例如 + @

(?:\[@[A-Za-z0-9\.\+\@]+\])

并根据需要进行更改:

private DrawerLayout drawer;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    setContentView(R.layout.activity_main);

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    BottomNavigationView bottomNavigationView = findViewById(R.id.bottomnavview);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            switch (menuItem.getItemId()){
                case R.id.call:
                    Intent intent = new Intent(Intent.ACTION_DIAL);
                    intent.setData(Uri.parse("tel:00902425262828"));
                    startActivity(intent);
                    break;

                case R.id.change_my_langg:

                    MenuView.ItemView.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {
                            showChangeLanguageDialog();

                            return false;
                        }
                        private void showChangeLanguageDialog(){
                            final String[] listItems = {"Turkish, English, Russian"};
                            final AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
                            mBuilder.setTitle("Select Language");
                            mBuilder.setSingleChoiceItems(listItems, -1, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int i) {
                                    if (i == 0){
                                        setLocale("TR");
                                        recreate();
                                    }

                                    else if (i == 1){
                                        setLocale("ENG");
                                        recreate();
                                    }

                                   else if (i == 2){
                                        setLocale("RU");
                                        recreate();
                                    }
                                   AlertDialog mDialog = mBuilder.create();
                                   mDialog.show();
                                }

                                private void setLocale(String lang) {
                                    Locale locale = new Locale(lang);
                                    Locale.setDefault(locale);
                                    Configuration configuration = new Configuration();
                                    configuration.locale = locale;
                                    getBaseContext().getResources().updateConfiguration(configuration, getBaseContext().getResources().getDisplayMetrics());

                                    SharedPreferences.Editor editor = getSharedPreferences("Settings", MODE_PRIVATE).edit();
                                    editor.putString("change_my_langg", lang);
                                    editor.apply();
                                }
                                public void loadLocale(){
                                    SharedPreferences prefs = getSharedPreferences("Settings",Activity.MODE_PRIVATE);
                                    String language = prefs.getString("change_my_langg","");
                                    setLocale(language);
                                }
                            });
                        }
                    });
                    break;

                case R.id.share:
                    Intent intent3 = new Intent(Intent.ACTION_SEND);
                    intent3.setType("text/plain");
                    String shareBody = "https://www.utopiaworld.com.tr/";
                    String shareSubject = "Utopia World Hotel";

                    intent3.putExtra(Intent.EXTRA_TEXT,shareBody);
                    intent3.putExtra(Intent.EXTRA_SUBJECT,shareSubject);
                    startActivity(Intent.createChooser(intent3,"Share Utopia World Hotel"));
                    break;

            }
            return false;
        }
    });



    drawer = findViewById(R.id.drawer_layout_home);
    NavigationView navigationView = findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                new HomeFragment()).commit();
        navigationView.setCheckedItem(R.id.nav_home);

    }

}



@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()) {
        case R.id.nav_home:
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                    new HomeFragment()).commit();
            break;
        case R.id.nav_directions: {
            Intent intent = new Intent(MainActivity.this, DirectionsFragment.class);
            startActivity(intent);
            break; }

        case R.id.nav_restaurant: {
            Intent intent = new Intent(MainActivity.this, RestaurantFragment.class);
            startActivity(intent); }
            break;

        case R.id.nav_webpage:
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                    new WebpageFragment()).commit();
            break;
        case R.id.nav_exit:
            System.exit(0);
            break;
    }

    drawer.closeDrawer(GravityCompat.START);
    return true;
}

@Override
public void onBackPressed() {
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

enter image description here

答案 3 :(得分:0)

x = 'Hello [@foo] how are you [@bar] more text'
out = re.search('((.*)(\[.*\])(.*))((\[.*\])(.*))',x)

获得上述输出后,您可以使用groups方法访问不同的组:

out.group(1)

'你好[@foo]你怎么样'


out.group(2)

“你好”


out.group(3)

'[[foo]'


out.group(4)

'你好吗'


out.group(5)

“ [@ bar]更多文字”


out.group(6)

'[@ bar]'


out.group(7)

“更多文字”